Avatar billede mad_man Nybegynder
26. juli 2003 - 10:26 Der er 35 kommentarer og
1 løsning

en lille fejlrette hjælp please.

jeg har stadig gang i min server der skal sende til bage til alle klients hvad jeg sender til den... nu er der bare et problem.. hvis der connecter en client og en mere osv osv.. det er ik problemet det er først et problem når der disconnecter en klient... så den næste klient der skriver noget til serveren bliver disconectet...
koder følger om 2 sec
/mad_man
Avatar billede mad_man Nybegynder
26. juli 2003 - 10:28 #1
#include <winsock.h>
#include <iostream>

#define PORT 21
#define buffersize 1024
#define MAXCONN 20

using namespace std;

//PROTOTYPER
bool sendvidere(SOCKET sock1);
void acceptconnection(SOCKET listener);
bool lukconn(SOCKET sock);
DWORD WINAPI handler(void* sock2);

//MAIN
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow)
{
    WORD sockver;
    WSADATA wsaData;
    int sock;
   
    sockver = MAKEWORD(1,1);
    WSAStartup(sockver,&wsaData);
   
    SOCKET listener;
    listener = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(listener == INVALID_SOCKET)
    {
        cout << "Invalid Socket: listener" << endl;
        WSACleanup();
        return 0;   
    }
    SOCKADDR_IN srv;
    srv.sin_family = AF_INET;
    srv.sin_addr.s_addr = INADDR_ANY;
    srv.sin_port = htons(PORT);
   
    sock = bind(listener, (LPSOCKADDR)&srv, sizeof(struct sockaddr));
   
    if(sock == SOCKET_ERROR)
    {
        cout << "Socket Error: bind listener og sock" << endl;
        WSACleanup();
        return 0;
    }
    sock = listen(listener,MAXCONN);
    acceptconnection(listener);
}
//SJOVER DER LIGGER HER
SOCKET sock[MAXCONN];
int nsock = 0;
//DEN DER ACCEPTERE NYE CONNS
void acceptconnection(SOCKET listener)
{
    sockaddr_in sinRemote;
    int nAddrsize = sizeof(sinRemote);
    while(1)
    {
        sock[nsock] = accept(listener, (sockaddr*)&sinRemote, &nAddrsize);
        if(sock[nsock] != INVALID_SOCKET)
        {       
            cout << "Klient connecter fra: " << inet_ntoa(sinRemote.sin_addr) << ":" << ntohs(sinRemote.sin_port) << "." << endl;
            DWORD nThreadID;
            CreateThread(0, 0, handler,(void*)sock[nsock], 0, &nThreadID);
            nsock++;
        }
        else
        {
            cout << "Invalid Socket: sock" << endl;
            WSACleanup();
            return;
        }
    }
}

//SENDVIDERE TIL ALLE KLIENTER FUNKTION
bool sendvidere(SOCKET sock1)
{
    SOCKET anothersock = (SOCKET)sock1;
    char rcvbuf[buffersize];
    int readbyte;
    int temp;
    do
    {
        readbyte = recv(anothersock,rcvbuf,buffersize,0);
        if(readbyte > 0)
        {
                cout << "Modtaget:" << readbyte << "byte(s)." << endl;
                for(int count = 0; count < nsock; count++)
                {
                    int sentbyte = 0;
                    while(sentbyte < readbyte)
                    {
                          int temp = send(sock[count],rcvbuf + sentbyte,readbyte - sentbyte,0);
                          if(temp > 0)
                          {
                              cout << "Sendt " << temp << " Byte(s) Tilbage Til: " << count << endl;
                              sentbyte += temp;
                          }
                          else if(temp == SOCKET_ERROR)
                          {
                              cout << "Socket Error: temp" << endl;
                              return false;
                          }
                          else
                          {
                              cout << "Klient smed forbindelsen uventet." << endl;
                              return true;
                          }
                    }
                }
        }
        else if(readbyte == SOCKET_ERROR)
        {
                cout << "Socket Error: readbyte" << endl;
                WSACleanup();
                return 0;
        }
    }while(readbyte != 0);
    cout << "Forbindelsen lukket af klienten" << endl;
    return true;
}

//handler
DWORD WINAPI handler(void* sock2)
{
    int fejl = 0;
    SOCKET moresock = (SOCKET)sock2;
    if(sendvidere(moresock))
    {
        fejl = 3;
    }
    cout << "Forbindelsen lukkes." << endl;
    if(lukconn(moresock))
    {
        cout << "Forbindelse er lukket." << endl;
    }
    else
    {
        fejl = 3;
    }
    return fejl;
}
//SKULLE LUKKE CONNECTIONS
bool lukconn(SOCKET sock)
{
    if(shutdown(sock,1) == SOCKET_ERROR)
    {
        cout << "Socket Error: shutdown" << endl;
        WSACleanup();
        return 0;
    }
    char rcvbuf[buffersize];
    while(1)
    {
        int nybyte = recv(sock, rcvbuf, buffersize, 0);
        if(nybyte == SOCKET_ERROR)
        {
            cout << "Socket Error: nybyte" << endl;
            WSACleanup();
            return 0;
        }
        else if(nybyte != 0)
        {
            cout << "Unknown Error occurced" << endl;
        }
        break;
    }
    if (closesocket(sock) == SOCKET_ERROR)
    {
        cout << "Socket Error: closesocket: sock" << endl;
        return 0;
    }
    return 1;
}


det min server skirver er:
Klient connecter fra: 192.168.1.4:1183.
Modtaget:1byte(s).
Sendt 1 Byte(s) Tilbage Til: 0
Forbindelsen lukket af klienten
Forbindelsen lukkes.
Forbindelse er lukket.
Klient connecter fra: 192.168.1.4:1184.
Modtaget:1byte(s).
Socket Error: temp
Forbindelsen lukkes.
Forbindelse er lukket.
Klient connecter fra: 192.168.1.4:1186.
Modtaget:1byte(s).
Socket Error: temp
Forbindelsen lukkes.
Forbindelse er lukket.
Avatar billede arne_v Ekspert
26. juli 2003 - 10:36 #2
For at hådntere det skal du nok have erstattet:

SOCKET sock[MAXCONN];
int nsock = 0;

med:

SOCKET sock[MAXCONN];
int inuse[MAXCONN];

sætte inuse til 0 (false) for alle ved opstart.

Ved connection bruger du så for(=0;<MAXCONN;++) for at finde den første
der ikke er ibrug, bruger den og sætter den til at være i brug.

Send til alle skal så igen for(=0;<MAXCONN;++) og sende til alle
der er ibrug.
Avatar billede mad_man Nybegynder
26. juli 2003 - 10:51 #3
??????????????????????
det fattede jeg ik lige helt...
Avatar billede arne_v Ekspert
26. juli 2003 - 11:24 #4
SOCKET sock[MAXCONN];
int inuse[MAXCONN];

for(int i=0;i<MAXCONN;i++) inuse[i]=0;

sockix = -1;
for(int i=0;i<MAXCONN;i++) if(!inuse[i]) sockix = i;
if(sockix == -1) {
  //gør noget grimt
}
      sock[sockix] = accept(listener, (sockaddr*)&sinRemote, &nAddrsize);
        if(sock[sockix] != INVALID_SOCKET)
        {     
            cout << "Klient connecter fra: " << inet_ntoa(sinRemote.sin_addr) << ":" << ntohs(sinRemote.sin_port) << "." << endl;
            DWORD nThreadID;
            CreateThread(0, 0, handler,(void*)sock[sockix], 0, &nThreadID);
            nsock++;
        }


              cout << "Modtaget:" << readbyte << "byte(s)." << endl;
                for(int count = 0; count < MAXCONN; count++)
                {
                  if(inuse[count])
                  {
                    int sentbyte = 0;
                    while(sentbyte < readbyte)
                    {
                          int temp = send(sock[count],rcvbuf + sentbyte,readbyte - sentbyte,0);
Avatar billede arne_v Ekspert
26. juli 2003 - 11:25 #5
Eller snakker jeg stadig sort ?
Avatar billede arne_v Ekspert
26. juli 2003 - 11:25 #6
Og et svar.
Avatar billede mad_man Nybegynder
26. juli 2003 - 11:29 #7
jeg tror jeg fatter lidt mere nu...
skal lige se om jeg kan få det til og du =)
Avatar billede mad_man Nybegynder
26. juli 2003 - 12:19 #8
//SJOVER DER LIGGER HER
SOCKET sock[MAXCONN];
int nsock;
int ibrug[MAXCONN];
int sockix;
//DEN DER ACCEPTERE NYE CONNS
void acceptconnection(SOCKET listener)
{
    for(int i=0;i<MAXCONN;i++) ibrug[i]=0;
   
    sockix = -1;
    for(int i=0;i<MAXCONN;i++) if(!ibrug[i]) sockix = i;
    if(sockix == -1)
    {
    cout << "Fatal error." << endl;
    return;
    }
   
    sockaddr_in sinRemote;
    int nAddrsize = sizeof(sinRemote);
    while(1)
    {   
        for(nsock = 0; nsock < MAXCONN; nsock++)
        {
            sock[sockix] = accept(listener, (sockaddr*)&sinRemote, &nAddrsize);
            if(sock[sockix] != INVALID_SOCKET)
            {       
                  cout << "Klient connecter fra: " << inet_ntoa(sinRemote.sin_addr) << ":" << ntohs(sinRemote.sin_port) << "." << endl;
                  DWORD nThreadID;
                  CreateThread(0, 0, handler,(void*)sock[sockix], 0, &nThreadID);
                  nsock++;
            }
            else
            {
                  cout << "Invalid Socket: sock" << endl;
                  WSACleanup();
                  return;
            }
        }
    }
}

//SENDVIDERE TIL ALLE KLIENTER FUNKTION
bool sendvidere(SOCKET sock1)
{
    SOCKET anothersock = (SOCKET)sock1;
    char rcvbuf[buffersize];
    int readbyte;
    int temp;
    do
    {
        readbyte = recv(anothersock,rcvbuf,buffersize,0);
        if(readbyte > 0)
        {
                cout << "Modtaget:" << readbyte << "byte(s)." << endl;
                for(int count = 0; count < nsock; count++)
                {
                  if(ibrug[count])
                  {
                    int sentbyte = 0;
                    while(sentbyte < readbyte)
                    {
                          int temp = send(sock[count],rcvbuf + sentbyte,readbyte - sentbyte,0);
                          if(temp > 0)
                          {
                              cout << "Sendt " << temp << " Byte(s) Tilbage Til: " << count << endl;
                              sentbyte += temp;
                          }
                          else if(temp == SOCKET_ERROR)
                          {
                              cout << "Socket Error: temp" << endl;
                              return false;
                          }
                          else
                          {
                              cout << "Klient smed forbindelsen uventet." << endl;
                              return true;
                          }
                    }
                  }
                }
        }
        else if(readbyte == SOCKET_ERROR)
        {
                cout << "Socket Error: readbyte" << endl;
                WSACleanup();
                return 0;
        }
    }while(readbyte != 0);
    cout << "Forbindelsen lukket af klienten" << endl;
    return true;
}

skulle det ik være sådan
Avatar billede mad_man Nybegynder
26. juli 2003 - 12:24 #9
nu acceptere den og modtager pakker med sender dem ik igen
Avatar billede mad_man Nybegynder
26. juli 2003 - 13:12 #10
jeg tror at problmet ligger i:
for(int count = 0; count < nsock; count++)
{
if(ibrug[count])

fordi der ligger den da 1 til count og skal den ik først gøre det efter if(ibrug[count]) ???
Avatar billede mad_man Nybegynder
26. juli 2003 - 13:19 #11
men hvordan skal man lave det om så det virker ????
Avatar billede arne_v Ekspert
26. juli 2003 - 14:49 #12
Ja der er vist blevet byttet lidt rundt på nogle ting.

Jeg prøver lige at reorganisere lidt.
Avatar billede arne_v Ekspert
26. juli 2003 - 14:59 #13
#include <winsock.h>
#include <iostream>

#define PORT 21
#define buffersize 1024
#define MAXCONN 20

using namespace std;

//PROTOTYPER
bool sendvidere(SOCKET sock1);
void acceptconnection(SOCKET listener);
bool lukconn(SOCKET sock);
DWORD WINAPI handler(void* sock2);

// AV
// CLIENT CONNECTIONS
SOCKET sock[MAXCONN];
int ibrug[MAXCONN];
// AV

//MAIN
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow)
{
    WORD sockver;
    WSADATA wsaData;
    int sock;
 
    sockver = MAKEWORD(1,1);
    WSAStartup(sockver,&wsaData);
 
    SOCKET listener;
    listener = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(listener == INVALID_SOCKET)
    {
        cout << "Invalid Socket: listener" << endl;
        WSACleanup();
        return 0; 
    }
    SOCKADDR_IN srv;
    srv.sin_family = AF_INET;
    srv.sin_addr.s_addr = INADDR_ANY;
    srv.sin_port = htons(PORT);
 
    sock = bind(listener, (LPSOCKADDR)&srv, sizeof(struct sockaddr));
 
    if(sock == SOCKET_ERROR)
    {
        cout << "Socket Error: bind listener og sock" << endl;
        WSACleanup();
        return 0;
    }
    sock = listen(listener,MAXCONN);
    for(int i=0;i<MAXCONN;i++) ibrug[i]=0; // AV
    acceptconnection(listener);
}


//DEN DER ACCEPTERE NYE CONNS
void acceptconnection(SOCKET listener)
{
    sockaddr_in sinRemote;
    int nAddrsize = sizeof(sinRemote);
    while(1)
    {
        // AV
        int sockix = -1;
        for(int i=0;i<MAXCONN;i++)
        {
          if(!ibrug[i])
          {
              sockix = i;
              break;
          }
        }
        if(sockix == -1) {
            //gør noget grimt
        }
        ibrug[sockix] = 1;
        sock[sockix] = accept(listener, (sockaddr*)&sinRemote, &nAddrsize);
        if(sock[sockix] != INVALID_SOCKET)
        {     
            cout << "Klient connecter fra: " << inet_ntoa(sinRemote.sin_addr) << ":" << ntohs(sinRemote.sin_port) << "." << endl;
            DWORD nThreadID;
            CreateThread(0, 0, handler,(void*)sock[sockix], 0, &nThreadID);
        }
        // AV
        else
        {
            cout << "Invalid Socket: sock" << endl;
            WSACleanup();
            return;
        }
    }
}

//SENDVIDERE TIL ALLE KLIENTER FUNKTION
bool sendvidere(SOCKET sock1)
{
    SOCKET anothersock = (SOCKET)sock1;
    char rcvbuf[buffersize];
    int readbyte;
    int temp;
    do
    {
        readbyte = recv(anothersock,rcvbuf,buffersize,0);
        if(readbyte > 0)
        {
                cout << "Modtaget:" << readbyte << "byte(s)." << endl;
                // AV
                for(int count = 0; count < MAXCONN; count++)
                {
                  if(ibrug[count])
                  {
                    // AV
                    int sentbyte = 0;
                    while(sentbyte < readbyte)
                    {
                          int temp = send(sock[count],rcvbuf + sentbyte,readbyte - sentbyte,0);
                          if(temp > 0)
                          {
                              cout << "Sendt " << temp << " Byte(s) Tilbage Til: " << count << endl;
                              sentbyte += temp;
                          }
                          else if(temp == SOCKET_ERROR)
                          {
                              cout << "Socket Error: temp" << endl;
                              return false;
                          }
                          else
                          {
                              cout << "Klient smed forbindelsen uventet." << endl;
                              return true;
                          }
                    }
                  } // AV
                }
        }
        else if(readbyte == SOCKET_ERROR)
        {
                cout << "Socket Error: readbyte" << endl;
                WSACleanup();
                return 0;
        }
    }while(readbyte != 0);
    cout << "Forbindelsen lukket af klienten" << endl;
    return true;
}

//handler
DWORD WINAPI handler(void* sock2)
{
    int fejl = 0;
    SOCKET moresock = (SOCKET)sock2;
    if(sendvidere(moresock))
    {
        fejl = 3;
    }
    cout << "Forbindelsen lukkes." << endl;
    if(lukconn(moresock))
    {
        cout << "Forbindelse er lukket." << endl;
    }
    else
    {
        fejl = 3;
    }
    return fejl;
}
//SKULLE LUKKE CONNECTIONS
bool lukconn(SOCKET sock)
{
    if(shutdown(sock,1) == SOCKET_ERROR)
    {
        cout << "Socket Error: shutdown" << endl;
        WSACleanup();
        return 0;
    }
    char rcvbuf[buffersize];
    while(1)
    {
        int nybyte = recv(sock, rcvbuf, buffersize, 0);
        if(nybyte == SOCKET_ERROR)
        {
            cout << "Socket Error: nybyte" << endl;
            WSACleanup();
            return 0;
        }
        else if(nybyte != 0)
        {
            cout << "Unknown Error occurced" << endl;
        }
        break;
    }
    if (closesocket(sock) == SOCKET_ERROR)
    {
        cout << "Socket Error: closesocket: sock" << endl;
        return 0;
    }
    return 1;
}
Avatar billede mad_man Nybegynder
26. juli 2003 - 15:33 #14
nu bliver klienten bare disconnectet når den sender den første byte (jeg bruger telnet til og teste med. er det forkert)
Avatar billede arne_v Ekspert
26. juli 2003 - 15:41 #15
Mystisk. Der burde jo ikke være ændret på noget logik.

I.s.f. bare at tælle klienter op, så finder vi første ledige
element til en ny klient.

Og i.s.f. at sende til alle så så sender vi kun til dem der er i brug.

Hm. Der mangler iøvrigt noget i det jeg har foreslået ! Nemlig noget kode
der får sat ibrug[ix] til 0 når en klient forsvinder igen.

Det var jo ligesom det der var hele pointen.
Avatar billede mad_man Nybegynder
26. juli 2003 - 15:55 #16
sernveren skriver:
Klient connecter fra: 192.168.1.4:2272.
Modtaget:1byte(s).
Sendt 1 Byte(s) Tilbage Til: 0
Socket Error: temp
Forbindelsen lukkes.
Forbindelse er lukket.
Avatar billede mad_man Nybegynder
26. juli 2003 - 15:56 #17
hvis der connecter flere lukker den også kun den der sender til serveren.. men den når og få det sendt videre...
det er ik så fedt at have et chat program hvor man kun må sende en linje så skal man connecte igen :/
Avatar billede mad_man Nybegynder
26. juli 2003 - 16:19 #18
ARGH nu har jeg fattet at ibrug[0] fx er den der gør sådan at den siger at 0 er i brug men skal der ik laves en liste over hvad der er i brug og hvad der ikke er ??? så den kan se at fx 2, 4 og 7 ikker er i brug ????
Avatar billede mad_man Nybegynder
26. juli 2003 - 16:21 #19
men sådan som det køere nu er der da ik nogle liste over hvad der ibrug og hvad der ik er og derfor når man sender noget til serveren så vil den sende til alle 20 klienter... selc om der er nogle af dem der ik er på.. og så får den SOCKET_ERROR og så lukker den forbindelsen til klienten...
Avatar billede arne_v Ekspert
26. juli 2003 - 16:28 #20
ibrug[0]=1 betyder at første slot er i brug
ibrug[0]=0 gør at den er ledig igen

og som jeg skrev så skal der laves noget til at få markeret når clients
er faldet af.
Avatar billede arne_v Ekspert
26. juli 2003 - 16:29 #21
Jeg tror at jeg blivet nødt til at prøve at køre programmet selv.

Men det kommer til at vente et par timer. Jeg tror nok at konen har
dikteret have arbejde nu.
Avatar billede mad_man Nybegynder
26. juli 2003 - 17:15 #22
jeg har fundet fejlen:
for(i= 0; i<MAXCONN; i++)
        {
          if(!ibrug[i])
          {
              sockix = i;
              cout << "set" << i << endl;
              break;
          }
den der setter ibrug[0] til 1 inden at der er connectet nogle clients
Avatar billede arne_v Ekspert
26. juli 2003 - 17:20 #23
Så skal der vel abre bytte som på:

        ibrug[sockix] = 1;
        sock[sockix] = accept(listener, (sockaddr*)&sinRemote, &nAddrsize);

til:

        sock[sockix] = accept(listener, (sockaddr*)&sinRemote, &nAddrsize);
        ibrug[sockix] = 1;
Avatar billede mad_man Nybegynder
26. juli 2003 - 17:26 #24
det har jeg prøvet.. det dur ik :/
Avatar billede mad_man Nybegynder
26. juli 2003 - 17:28 #25
skal du prøve at køre programmet
så kan jeg lige smide hele sourcen til dig... jeg bruger dev c++ til at compile med...
Avatar billede mad_man Nybegynder
26. juli 2003 - 17:34 #26
hmmmm når man connecter og disconnecter og connecter igen så tager den ik den samme som man connectede på først med den næste... ????
for(i=0; i<MAXCONN; i++)
det er somom at i ik bliver sat til 0 igen
Avatar billede arne_v Ekspert
26. juli 2003 - 18:20 #27
Det sidste kan jeg godt forklare.

Det er vel fordi vi ikke har fået sat ibrug[0] til 0 ved disconnect.
Avatar billede arne_v Ekspert
26. juli 2003 - 18:20 #28
Men prøv og smid en fuld source så vil jeg prøve at køre den.
Avatar billede mad_man Nybegynder
26. juli 2003 - 18:49 #29
#include <winsock.h>
#include <iostream>

#define PORT 21
#define buffersize 1024
#define MAXCONN 20

using namespace std;

//PROTOTYPER
bool sendvidere(SOCKET sock1);
void acceptconnection(SOCKET listener);
bool lukconn(SOCKET sock);
DWORD WINAPI handler(void* sock2);

//CLIEN CONNECTIONS
SOCKET sock[MAXCONN];
int ibrug[MAXCONN];
int i;
int sockix = -1;

//MAIN
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow)
{
    WORD sockver;
    WSADATA wsaData;
    int sock;
   
    sockver = MAKEWORD(1,1);
    WSAStartup(sockver,&wsaData);
   
    SOCKET listener;
    listener = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(listener == INVALID_SOCKET)
    {
        cout << "Invalid Socket: listener" << endl;
        WSACleanup();
        return 0;   
    }
    SOCKADDR_IN srv;
    srv.sin_family = AF_INET;
    srv.sin_addr.s_addr = INADDR_ANY;
    srv.sin_port = htons(PORT);
   
    sock = bind(listener, (LPSOCKADDR)&srv, sizeof(struct sockaddr));
   
    if(sock == SOCKET_ERROR)
    {
        cout << "Socket Error: bind listener og sock" << endl;
        WSACleanup();
        return 0;
    }
    sock = listen(listener,MAXCONN);
    for(i=0;i<MAXCONN;i++)
    {
        ibrug[i]=0;
    }
    acceptconnection(listener);
}

//DEN DER ACCEPTERE NYE CONNS
void acceptconnection(SOCKET listener)
{   
    sockaddr_in sinRemote;
    int nAddrsize = sizeof(sinRemote);
   
    while(1)
    {
        for(i=0; i<MAXCONN; i++)
        {
          if(!ibrug[i])
          {
              sockix = i;
              break;
          }
        }
        if(sockix == -1) {
            //gør noget grimt
        }

        cout << "set1: " << i << endl;
        sock[sockix] = accept(listener, (sockaddr*)&sinRemote, &nAddrsize);
        ibrug[sockix] = 1;
        if(sock[sockix] != INVALID_SOCKET)
        {       
            cout << "Klient connecter fra: " << inet_ntoa(sinRemote.sin_addr) << ":" << ntohs(sinRemote.sin_port) << "." << endl;
            DWORD nThreadID;
            CreateThread(0, 0, handler,(void*)sock[sockix], 0, &nThreadID);
        }
        else
        {
            cout << "Invalid Socket: sock" << endl;
            WSACleanup();
            return;
        }
       
    }
}

//SENDVIDERE TIL ALLE KLIENTER FUNKTION
bool sendvidere(SOCKET sock1)
{
    SOCKET anothersock = (SOCKET)sock1;
    char rcvbuf[buffersize];
    int readbyte;
    int temp;
    do
    {
        readbyte = recv(anothersock,rcvbuf,buffersize,0);
        if(readbyte > 0)
        {
                cout << "Modtaget:" << readbyte << "byte(s)." << endl;
                for(int count = 0; count < MAXCONN; count++)
                {
                cout << "ibrug[" << count << "] = " << ibrug[count] << endl;
                if(ibrug[count])
                {
                cout << "test: "<< count << endl;
               
                    int sentbyte = 0;
                    while(sentbyte < readbyte)
                    {
                          int temp = send(sock[count],rcvbuf + sentbyte,readbyte - sentbyte,0);
                          if(temp > 0)
                          {
                              cout << "Sendt " << temp << " Byte(s) Tilbage Til: " << count << endl;
                              sentbyte += temp;
                          }
                          else if(temp == SOCKET_ERROR)
                          {
                              cout << "Socket Error: temp" << endl;
                              return false;
                          }
                          else
                          {
                              cout << "Klient smed forbindelsen uventet." << endl;
                              return true;
                          }
                    }
                  }
                  else
                  {
                  cout << "den her buerde du ik se" << endl;
                  }
                }
        }
        else if(readbyte == SOCKET_ERROR)
        {
                cout << "Socket Error: readbyte" << endl;
                WSACleanup();
                return 0;
        }
    }while(readbyte != 0);
    cout << "Forbindelsen lukket af klienten" << endl;
    return true;
}

//handler
DWORD WINAPI handler(void* sock2)
{
    int fejl = 0;
    SOCKET moresock = (SOCKET)sock2;
    if(sendvidere(moresock))
    {
        fejl = 3;
    }
    cout << "Forbindelsen lukkes." << endl;
    if(lukconn(moresock))
    {
        ibrug[i] = 0;
        cout << "set0: " << i << endl;
        cout << "Forbindelse er lukket." << endl;
    }
    else
    {
        fejl = 3;
    }
    return fejl;
}
//SKULLE LUKKE CONNECTIONS
bool lukconn(SOCKET sock)
{
    if(shutdown(sock,1) == SOCKET_ERROR)
    {
        cout << "Socket Error: shutdown" << endl;
        WSACleanup();
        return 0;
    }
    char rcvbuf[buffersize];
    while(1)
    {
        int nybyte = recv(sock, rcvbuf, buffersize, 0);
        if(nybyte == SOCKET_ERROR)
        {
            cout << "Socket Error: nybyte" << endl;
            WSACleanup();
            return 0;
        }
        else if(nybyte != 0)
        {
            cout << "Unknown Error occurced" << endl;
        }
        break;
    }
    if (closesocket(sock) == SOCKET_ERROR)
    {
        cout << "Socket Error: closesocket: sock" << endl;
        return 0;
    }
    return 1;
}
Avatar billede mad_man Nybegynder
26. juli 2003 - 18:50 #30
det skulle jeg mene at det var det hele
og jeg sætter også ibrug[i] tilbage til 0 når jeg lukker
Avatar billede arne_v Ekspert
26. juli 2003 - 20:26 #31
Følgende virker hos mig:

#include <winsock.h>
#include <iostream>

#define PORT 60000
#define buffersize 1024
#define MAXCONN 20

using namespace std;

//PROTOTYPER
bool sendvidere(SOCKET sock1);
void acceptconnection(SOCKET listener);
bool lukconn(SOCKET sock);
DWORD WINAPI handler(void* sock2);

//CLIENT CONNECTIONS
SOCKET sock[MAXCONN];
bool ibrug[MAXCONN];

//MAIN
int main()
{
    WORD sockver = MAKEWORD(1,1);
    WSADATA wsaData;
    WSAStartup(sockver,&wsaData);
 
    SOCKET listener;
    listener = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(listener == INVALID_SOCKET)
    {
        cout << "Invalid Socket: listener" << endl;
        WSACleanup();
        return 0; 
    }

    SOCKADDR_IN srv;
    srv.sin_family = AF_INET;
    srv.sin_addr.s_addr = INADDR_ANY;
    srv.sin_port = htons(PORT);
    int stat = bind(listener, (LPSOCKADDR)&srv, sizeof(struct sockaddr));
    if(stat == SOCKET_ERROR)
    {
        cout << "Socket Error: bind listener og sock" << endl;
        WSACleanup();
        return 0;
    }

    stat = listen(listener,MAXCONN);

    for(int i=0;i<MAXCONN;i++)
    {
        ibrug[i]=false;
    }

    acceptconnection(listener);
   
    return 0;
}

//DEN DER ACCEPTERE NYE CONNS
void acceptconnection(SOCKET listener)

    sockaddr_in sinRemote;
    int nAddrsize = sizeof(sinRemote);
 
    while(1)
    {
        int sockix = -1;
        for(int i=0; i<MAXCONN; i++)
        {
          if(!ibrug[i])
          {
              sockix = i;
              break;
          }
        }
        if(sockix == -1) {
            cout << "Ikke plads til klient - aborting" << endl;
            WSACleanup();
            return;
        }

        sock[sockix] = accept(listener, (sockaddr*)&sinRemote, &nAddrsize);
        cout << "Accept på klient element " << sockix << endl;

        if(sock[sockix] != INVALID_SOCKET)
        {     
            ibrug[sockix] = true;
            cout << "Klient connecter fra: " << inet_ntoa(sinRemote.sin_addr) << ":" << ntohs(sinRemote.sin_port) << "." << endl;
            cout << "Tildelt klient element " << sockix << endl;
            cout << "Socket " << sock[sockix] << endl;
            DWORD nThreadID;
            CreateThread(0, 0, handler,(void*)&sock[sockix], 0, &nThreadID);
        }
        else
        {
            cout << "Invalid Socket: sock" << endl;
            WSACleanup();
            return;
        }
     
    }
}

//SENDVIDERE TIL ALLE KLIENTER FUNKTION
bool sendvidere(SOCKET sock1)
{
    char rcvbuf[buffersize];
    int readbyte;
    int temp;
    do
    {
        cout << "Recv socket " << sock1 << endl;
        readbyte = recv(sock1,rcvbuf,buffersize,0);
        if(readbyte > 0)
        {
                cout << "Modtaget:" << readbyte << "byte(s)." << endl;
                for(int count = 0; count < MAXCONN; count++)
                {
                if(ibrug[count])
                {
                    int sentbyte = 0;
                    while(sentbyte < readbyte)
                    {
                          cout << "Send socket " << sock[count] << endl;
                          int temp = send(sock[count],rcvbuf + sentbyte,readbyte - sentbyte,0);
                          if(temp > 0)
                          {
                              cout << "Sendt " << temp << " Byte(s) Tilbage Til: " << count << endl;
                              sentbyte += temp;
                          }
                          else if(temp == SOCKET_ERROR)
                          {
                              cout << "Socket Error: temp" << endl;
                              return false;
                          }
                          else
                          {
                              cout << "Klient smed forbindelsen uventet." << endl;
                              return true;
                          }
                    }
                  }
                }
        }
        else if(readbyte == SOCKET_ERROR)
        {
                cout << "Socket Error: readbyte" << endl;
                WSACleanup();
                return 0;
        }
    }while(readbyte != 0);
    cout << "Forbindelsen lukket af klienten" << endl;
    return true;
}

//handler
DWORD WINAPI handler(void* sock2_)
{
    int fejl = 0;
    SOCKET sock2 = *((SOCKET*)sock2_);
    if(sendvidere(sock2))
    {
        fejl = 3;
    }
    cout << "Forbindelsen lukkes." << endl;
    if(lukconn(sock2))
    {
        ibrug[(SOCKET *)sock2_-sock] = false;
        cout << "Forbindelse er lukket." << endl;
        cout << "Element " << ((SOCKET *)sock2_-sock) << " klar igen" << endl;
    }
    else
    {
        fejl = 3;
    }
    return fejl;
}

//SKULLE LUKKE CONNECTIONS
bool lukconn(SOCKET sock)
{
    if(shutdown(sock,1) == SOCKET_ERROR)
    {
        cout << "Socket Error: shutdown" << endl;
        return 0;
    }
    if (closesocket(sock) == SOCKET_ERROR)
    {
        cout << "Socket Error: closesocket: sock" << endl;
        return 0;
    }
    return 1;
}
Avatar billede mad_man Nybegynder
26. juli 2003 - 20:43 #32
det ser ud til og virke... efter mange lange anstrænglser =)
tak for hjælpen
Avatar billede arne_v Ekspert
26. juli 2003 - 20:46 #33
Er der nogenspørgsmål til rettelserne ?

Den mest tricky er nok den måde jeg beregner sock index på i lukconn.
Avatar billede mad_man Nybegynder
26. juli 2003 - 20:48 #34
ja ok den ville nok lidt foklaring nok hjælpe på forståelsen
Avatar billede arne_v Ekspert
26. juli 2003 - 20:56 #35
Vi har et sock array.

Når vi creater tråde sender vi adressen på det element der hører
til tråden med over &sock[sockix].

I handler er arguemntet erklæret til void *, men det konverterer
vi tilbage til en SOCKET * og hapser værdien med
SOCKET sock2 = *((SOCKET*)sock2_), så vi har en socket vi
kan bruge.

Problemet er når vi skal have sat ibrug til false. Der skal vi nemlig ikke
bruge socket med index i socket array.

(SOCKET *)sock2_-sock finder imidlertid det index.

Vi trækker adressen fra første element i socket arrayet fra
adressen på det element vi har gang i. Og fordi typerne er rigtige
så kan C (C++) beregne index rigtigt (den dividerer selv med 4 som er
størrelsen på en SOCKET).
Avatar billede mad_man Nybegynder
27. juli 2003 - 10:17 #36
efter jeg har haft en nat til og få det hele til og falde på plads tror jeg, jeg har fattet det =)
igen tak for den gode hjælp
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester