Server/Client-TCP asynchron (winsock) // FD_WRITE Problem

Brauche ich Eure Hilfe, denn ich habe zwei Konsolen-Anwendung in C++ : ein client schicken zu können, wie viele Strings wie möglich zu einem server (in der Reihenfolge zu senden, Koordinaten). Es gelang mir, um einer Sperrung Steckdose, aber wie habe ich das zu integrieren, nachdem in einer Entwicklungs-Plattform (3D ÜBER Virtools), die nennen mein script jeden frame, habe ich keine andere Lösung als die Verwendung von asynchronen sockets.

*Mein problem ist, dass ich nur E-saite einmal, und nachdem ich nicht erhalten, FD_WRITE mehr...*

Diese beginnen, fahren Sie mich verrückt, so jede Hilfe wird sehr geschätzt werden (ich bin ein Anfänger in der Programmierung), vielen Dank im Voraus an alle, die das Gefühl ein wenig besorgt über mein problem

Hier ist mein code,

Server

#include <winsock2.h> 
#include <Windows.h> 
#include <conio.h> 

#pragma comment(lib, "ws2_32.lib") 

#define   SOCKET_ERRNO   WSAGetLastError() 
#define ADDRESS "127.0.0.1" 
#define PORT 1234 

static SOCKET ListenFirstFreePort() 
{ 
   struct sockaddr_in addr; 
   int len = sizeof(addr);    
   SOCKET hSocket; 

   //Create socket 
   hSocket = socket( PF_INET, SOCK_STREAM, 0 ); 
   if( hSocket == INVALID_SOCKET ) 
   { 
      printf( "socket() error %d\n", SOCKET_ERRNO ); 
      exit(1); 
   } 

   //Connexion setting for local connexion 
   addr.sin_family = AF_INET ; 
   addr.sin_addr.s_addr = inet_addr(ADDRESS); 
   addr.sin_port = htons (PORT); 

   //bind socket 
   if ( bind( hSocket, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR ) 
   { 
      printf( "bind() error %d\n", SOCKET_ERRNO ); 
      exit(1); 
   } 

   //listen 
   if ( listen( hSocket, 100) == SOCKET_ERROR ) 
   { 
      printf( "listen() error %d\n", SOCKET_ERRNO ); 
      exit(1); 
   } 

   return hSocket; 
} 



void main() 
{ 
   WSADATA stack_info; 
   SOCKET ahSocket[2]; 
   WSAEVENT ahEvents[2]; 
   DWORD dwEvent; 
   WSANETWORKEVENTS NetworkEvents; 
   int rc; 

   //Initialize Winsock 
   WSAStartup(MAKEWORD(2,0), &stack_info) ; 

   //Create events 
   ahEvents[0] = WSACreateEvent(); 
   ahEvents[1] = WSACreateEvent(); 


   //Create listening socket 
   ahSocket[0] = ListenFirstFreePort(); 
   rc = WSAEventSelect(ahSocket[0], ahEvents[0], FD_ACCEPT ); 
   if( rc == SOCKET_ERROR ) 
   { 
      printf( "WSAEventSelect() error %d\n", SOCKET_ERRNO ); 
      exit(1); 
   } 

   while (TRUE) 
   { 
      //Waiting for so;ething to happen 
      //Basically we'll firstly receive the connexion of the client socket 
      //and then we'll be notificated when there will be some data to read 

      //look for events 
      dwEvent = WSAWaitForMultipleEvents( 2, ahEvents, FALSE, WSA_INFINITE, FALSE); 

      switch (dwEvent) 
      { 
      case WSA_WAIT_FAILED: 
         printf("WSAEventSelect: %d\n", WSAGetLastError()); 
         break; 
      case WAIT_IO_COMPLETION: 
      case WSA_WAIT_TIMEOUT: 
         break; 

      default: 

         //if there is one dwEvent-WSA_WAIT_EVENT_0 has to be substracted so as to dwEvent correspond to the index of the concerned socket 
         dwEvent -= WSA_WAIT_EVENT_0; 

         //enumeration of the events on the socket[dwEvent] 
         if (SOCKET_ERROR == WSAEnumNetworkEvents(ahSocket[dwEvent], ahEvents[dwEvent], &NetworkEvents)) 
         { 
            printf("WSAEnumNetworkEvent: %d lNetworkEvent %X\n",  
               WSAGetLastError(), NetworkEvents.lNetworkEvents); 
            NetworkEvents.lNetworkEvents = 0; 
         } 
         else  
         { 

            if (FD_CLOSE   & NetworkEvents.lNetworkEvents) 
            { 

               printf( "FD_CLOSE ok (dwEvent=%d)\n", dwEvent ); 
               printf( "press a key to exit\n" ); 
               getch(); //require conio.h 

               WSACloseEvent( ahEvents[0] ); 
               WSACloseEvent( ahEvents[1] ); 
               exit(0); 
            } 
            if (FD_READ & NetworkEvents.lNetworkEvents) 
            { 
               char szBuffer[256]; int cbRecv; 

               //Only the second socket expect to receive data 
               printf( "FD_READ ok (dwEvent=%d)\n", dwEvent ); 

               //read data 
               cbRecv = recv( ahSocket[dwEvent], szBuffer, sizeof(szBuffer) - 1, 0 ); 
               if( cbRecv <= 0 ) 
               { 
                  printf( "recv() error %d\n", SOCKET_ERRNO ); 
                  exit(1); 
               } 

               //On ecrit ce paquet (On remet le 0 au cas ou le paquet 
               //ait ete coupe en 2 - je sais, ca n'arrivera jamais en local) 
               //we put the 0 in case it has been cut - unlikey to happen on local network 
               szBuffer[cbRecv] = 0; 

               //write data in console window 
               printf( "socket %d : '%s'\n", dwEvent, szBuffer ); 
            } 
         } 
         if (FD_ACCEPT & NetworkEvents.lNetworkEvents) 
         { 
            struct sockaddr_in addrAccept; 
            int lenAccept; 
            lenAccept = sizeof( addrAccept ); 

            //we should have dwEvent=0 
            printf( "accept ok (dwEvent=%d)\n", dwEvent ); 

            //we create another socket to accept the connexion with the client socket 
            ahSocket[1] = accept(ahSocket[dwEvent], (struct sockaddr *)&addrAccept, &lenAccept); 

            //we want to be informed on when we'll be able read data from it 
            rc = WSAEventSelect(ahSocket[1], ahEvents[1], FD_READ|FD_CLOSE  ); 
            if( rc == SOCKET_ERROR ) 
            { 
               printf( "WSAEventSelect() error %d\n", SOCKET_ERRNO ); 
               exit(1); 
            } 
         } 
      } 
   } 
} 

Client

#include <winsock2.h> 
#include <conio.h> 
#include <time.h> 

#pragma comment(lib, "ws2_32.lib") 

#define   SOCKET_ERRNO   WSAGetLastError() 
#define ADDRESS "127.0.0.1" 
#define PORT 1234 

SOCKET ConnectToPort() 
{ 
   struct sockaddr_in addr; 
   SOCKET hSocket; 
   u_long arg; int err; 

   //Create socket 
   hSocket = socket( PF_INET, SOCK_STREAM, 0 ); 
   if( hSocket == INVALID_SOCKET ) 
   { 
      printf( "socket() error %d\n", SOCKET_ERRNO ); 
      exit(1); 
   } 

   //Connexion setting for local connexion 
   addr.sin_family = AF_INET ; 
   addr.sin_addr.s_addr = inet_addr(ADDRESS); 
   addr.sin_port = htons (PORT); 

   //Connect 
   if( connect( hSocket, (struct sockaddr *)&addr, sizeof(addr) ) == SOCKET_ERROR ) 
   { 
      //As we are in non-blocking mode we'll always have the error 
      //WSAEWOULDBLOCK whichis actually not one 
      if( SOCKET_ERRNO != WSAEWOULDBLOCK ) 
      { 
         printf( "connect() error (%d)\n", SOCKET_ERRNO ); 
         exit(1); 
      } 
   } 

   return hSocket; 
} 



void main() 
{ 
   int initClockTime; 
   WSADATA stack_info; 
   SOCKET ahSocket[1]; 
   WSAEVENT ahEvents[1]; 
   DWORD dwEvent; 
   WSANETWORKEVENTS NetworkEvents; 
   int rc; 

   //Initialize Winsock 
   WSAStartup(MAKEWORD(2,0), &stack_info) ; 

   //Create event 
   ahEvents[0] = WSACreateEvent(); 

   //Create and connect a socket on the server socket 
   ahSocket[0]= ConnectToPort(); 

   //not sure if I have to use or not 
   /*u_long arg = 1; 
   ioctlsocket( ahSocket[0] , FIONBIO, &arg );*/ 

   //the application wants to receive notification of a completed connection 
   rc = WSAEventSelect(ahSocket[0], ahEvents[0], FD_CONNECT  ); 
   if( rc == SOCKET_ERROR ) 
   { 
      printf( "WSAEventSelect() error %d\n", SOCKET_ERRNO ); 
      exit(1); 
   } 

   while (TRUE) 
   { 
      //look for events 
      dwEvent = WSAWaitForMultipleEvents( 1, ahEvents, FALSE, 1000, FALSE); 

      switch (dwEvent) 
      { 
      case WSA_WAIT_FAILED: 
         printf("WSAEventSelect: %d\n", WSAGetLastError()); 
         break; 
      case WAIT_IO_COMPLETION: 
      case WSA_WAIT_TIMEOUT: 
         break; 

      default: 

         printf("while\n"); 

         //if there is one dwEvent-WSA_WAIT_EVENT_0 has to be substracted so as to dwEvent correspond to the index of the concerned socket 
         dwEvent -= WSA_WAIT_EVENT_0; 

         //enumeration of the events on the socket[dwEvent] 
         if (SOCKET_ERROR == WSAEnumNetworkEvents(ahSocket[dwEvent], ahEvents[dwEvent], &NetworkEvents)) 
         { 
            printf("WSAEnumNetworkEvent: %d lNetworkEvent %X\n", WSAGetLastError(), NetworkEvents.lNetworkEvents); 
            NetworkEvents.lNetworkEvents = 0; 
         } 
         else  
         { 


            if (FD_CONNECT & NetworkEvents.lNetworkEvents) 
            { 
               //connexion is OK 
               printf( "FD_CONNECT ok (dwEvent=%d)\n", dwEvent ); 

               //now that we are connected we want to send data or be aware when the other socket is disconnected 
               rc = WSAEventSelect(ahSocket[dwEvent], ahEvents[dwEvent], FD_CLOSE | FD_WRITE ); 
               if( rc == SOCKET_ERROR ) 
               { 
                  printf( "WSAEventSelect() error %d\n", SOCKET_ERRNO ); 
                  exit(1); 
               } 
            } 
            if (FD_CLOSE   & NetworkEvents.lNetworkEvents) 
            { 
               printf( "FD_CLOSE ok (dwEvent=%d)\n", dwEvent ); 
               printf( "press a key to exit\n" ); 
               getch(); 

               WSACloseEvent( ahEvents[0] ); 
               exit(0); 
            } 

            if (FD_WRITE & NetworkEvents.lNetworkEvents) 
            { 
               char szBuffer[256]; int cbBuffer; 

               printf( "FD_WRITE ok (dwEvent=%d)\n", dwEvent ); 

               //create string and return the size 
               cbBuffer = sprintf( szBuffer, "Coucou", dwEvent ); 


               //send the string with 0 at the end 
               rc = send( ahSocket[dwEvent], szBuffer, cbBuffer + 1, 0 ); 
               if (SOCKET_ERROR ==  rc) 
               { 
                  printf("WSAEnumNetworkEvent: %d lNetworkEvent %X\n",  WSAGetLastError(), NetworkEvents.lNetworkEvents); 
               } 

               //not sure if I have to use it 
               //WSAResetEvent(ahEvents[0]); 

            } 

         } 
      } 
   } 
} 

herunterladen .cpp-Dateien : https://www.dropbox.com/s/pjuipz7v4iwr5ea/Clientserver%20TCP.zip

InformationsquelleAutor user1637091 | 2012-08-30

Schreibe einen Kommentar