// // Universal Internet Client // // Usage: // client [IP_address_of_server [port_of_server]] // where IP_address_of_server is either IP number of server // or a symbolic Internet name, default is "localhost"; // port_of_server is a port number, default is 1234. // #include #include #include #include #include static void usage(); // Receiving thread body function static DWORD WINAPI receiveMessages(void* arg); static HANDLE hReceivingThread = NULL; static DWORD receivingThreadID = 0; static CRITICAL_SECTION critSect; static int s0 = (-1); // Socket number static char receiveBuffer[1024]; static char sendBuffer[1024]; int main(int argc, char *argv[]) { if (argc > 1 && *(argv[1]) == '-') { usage(); exit(1); } InitializeCriticalSection(&critSect); // Initialize Winsock DLL WORD wVersionRequested = MAKEWORD(2, 2); WSADATA wsaData; int err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { printf("WSAStartup failed with error: %d\n", err); exit(-1); } // Create a socket s0 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s0 < 0) { printf( "Could not create a socket: error=%d\n", WSAGetLastError() ); } // Fill in the address of server struct sockaddr_in peeraddr; memset(&peeraddr, 0, sizeof(peeraddr)); const char* peerHost = "localhost"; if (argc > 1) peerHost = argv[1]; // Resolve the server address (convert from symbolic name to IP number) struct hostent *host = gethostbyname(peerHost); if (host == NULL) { perror("Cannot define host address"); exit(1); } peeraddr.sin_family = AF_INET; short peerPort = 1234; if (argc >= 3) peerPort = (short) atoi(argv[2]); peeraddr.sin_port = htons(peerPort); // Print a resolved address of server (the first IP of the host) printf( "peer addr = %d.%d.%d.%d, port %d\n", (int) host->h_addr_list[0][0] & 0xff, (int) host->h_addr_list[0][1] & 0xff, (int) host->h_addr_list[0][2] & 0xff, (int) host->h_addr_list[0][3] & 0xff, (int) peerPort ); // Write resolved IP address of a server to the address structure memmove(&(peeraddr.sin_addr.s_addr), host->h_addr_list[0], 4); // Connect to a remote server int res = connect(s0, (struct sockaddr*) &peeraddr, sizeof(peeraddr)); if (res < 0) { printf( "Cannot connect: err=%d\n", WSAGetLastError() ); exit(1); } printf("Connected!\n"); fflush(stdout); // Create a receiving thread hReceivingThread = CreateThread( NULL, // lpThreadAttributes 0, // dwStackSize - default &receiveMessages, // thread starting function NULL, // parameter of thread starting function 0, // dwCreationFlags &receivingThreadID ); if (hReceivingThread == NULL) { printf( "Cannot create receiving thread: error %d\n", (int) GetLastError() ); exit(-1); } // Read messages from the keyboard and send // them to remote server while (true) { int s; EnterCriticalSection(&critSect); s = s0; LeaveCriticalSection(&critSect); if (s < 0) break; if (fgets(sendBuffer, 1022, stdin) == NULL) break; size_t len = strlen(sendBuffer); EnterCriticalSection(&critSect); s = s0; LeaveCriticalSection(&critSect); if (s < 0) break; if ( strcmp(sendBuffer, ".\n") == 0 || strcmp(sendBuffer, ".\r\n") == 0 ) { // Close the connection EnterCriticalSection(&critSect); s0 = (-1); LeaveCriticalSection(&critSect); closesocket(s); break; } if (len > 0) { // Send data to server res = send(s, sendBuffer, len, 0); if (res < 0) { printf( "Cannot send data: err=%d\n", WSAGetLastError() ); EnterCriticalSection(&critSect); s = s0; s0 = (-1); LeaveCriticalSection(&critSect); closesocket(s); break; } } } // end while // Socket is closed already! WaitForSingleObject(hReceivingThread, INFINITE); CloseHandle(hReceivingThread); WSACleanup(); DeleteCriticalSection(&critSect); return 0; } static void usage() { printf( "A simple Internet client application.\n" "Usage:\n" " client [IP_address_of_server [port_of_server]]\n" " where IP_address_of_server is either IP number of server\n" " or a symbolic Internet name, default is \"localhost\";\n" " port_of_server is a port number, default is 1234.\n" "The client connects to a server which address is given in a\n" "command line, receives messages from a server, and sends messages\n" "that a user prints on keyboard.\n" ); } static DWORD WINAPI receiveMessages(void* /* arg */) { // printf("Receiving thread is started.\n"); // fflush(stdout); while (true) { int s; EnterCriticalSection(&critSect); s = s0; LeaveCriticalSection(&critSect); if (s < 0) break; int res = recv(s, receiveBuffer, 1022, 0); // printf("Received %d bytes.\n", res); // fflush(stdout); if (res <= 0) { /*... if (res < 0) { printf( "Receive error: err=%d\n", WSAGetLastError() ); fflush(stdout); } ...*/ EnterCriticalSection(&critSect); s0 = (-1); LeaveCriticalSection(&critSect); closesocket(s); break; } receiveBuffer[res] = 0; printf("%s", receiveBuffer); fflush(stdout); } return 0; }