服務端代碼server.c
// server.cpp : Defines the entry point for the console application. // #include <stdio.h> #include <Winsock2.h> //Socket的函數調用 #include <windows.h> #define BUF_SIZE 6400 // 緩沖區大小 #pragma comment (lib, "ws2_32") // 使用WINSOCK2.H時,則需要庫文件WS2_32.LIB DWORD WINAPI Rcv( LPVOID lpParam ) { SOCKET sClient = *(SOCKET*)lpParam; int retVal; char bufRecv[BUF_SIZE]; memset( bufRecv, 0, sizeof( bufRecv ) ); while(1) { retVal = recv( sClient, bufRecv, BUF_SIZE, 0 ); if ( retVal == SOCKET_ERROR ) { printf( "recive faild!\n" ); break; } else { printf( "收到客戶端消息:%s\n", bufRecv ); } } return 0; } DWORD WINAPI Snd( LPVOID lpParam ) { SOCKET sClient = *(SOCKET*)lpParam; int retVal; char bufSend[BUF_SIZE]; memset( bufSend, 0, sizeof( bufSend ) ); while(1) { gets( bufSend ); retVal = send( sClient, bufSend, strlen(bufSend)+sizeof(char), 0 ); if ( retVal == SOCKET_ERROR ) { printf( "send faild!\n" ); break; } } return 0; } int main(int argc, char* argv[]) { // 初始化套接字動態庫 WSADATA wsaData; if ( WSAStartup(MAKEWORD(2, 2), &wsaData) != 0 ) { printf( "winsock load faild!\n" ); return 1; } // 創建服務段套接字 SOCKET sServer = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( sServer == INVALID_SOCKET ) { printf( "socket faild!\n" ); WSACleanup(); return -1; } // 服務端地址 sockaddr_in addrServ; addrServ.sin_family = AF_INET; addrServ.sin_port = htons( 9999 ); addrServ.sin_addr.s_addr = htonl( INADDR_ANY ); // 綁定套接字 if ( bind( sServer, ( const struct sockaddr* )&addrServ, sizeof(addrServ) ) == SOCKET_ERROR ) { printf( "bind faild!\n" ); closesocket( sServer ); WSACleanup(); return -1; } printf("Server is On IP:[%s],port:[%d]\n",inet_ntoa(addrServ.sin_addr),ntohs(addrServ.sin_port)); // 監聽套接字 數字表示最多能監聽客戶個數 if ( listen( sServer, 5 ) == SOCKET_ERROR ) { printf( "listen faild!\n" ); closesocket( sServer ); WSACleanup(); return -1; } SOCKET sClient; // 客戶端套接字 sockaddr_in addrClient; int addrClientLen = sizeof( addrClient ); sClient = accept( sServer, ( sockaddr FAR* )&addrClient, &addrClientLen ); if ( sClient == INVALID_SOCKET ) { printf( "accept faild!\n" ); closesocket( sServer ); WSACleanup(); return -1; } printf("accepted client IP:[%s],port:[%d]\n",inet_ntoa(addrClient.sin_addr),ntohs(addrClient.sin_port)); HANDLE hThread1, hThread2; DWORD dwThreadId1, dwThreadId2; hThread1 = ::CreateThread(NULL, NULL, Snd, (LPVOID*)&sClient, 0, &dwThreadId1); hThread2 = ::CreateThread(NULL, NULL, Rcv, (LPVOID*)&sClient, 0, &dwThreadId2); ::WaitForSingleObject(hThread1, INFINITE); ::WaitForSingleObject(hThread2, INFINITE); ::CloseHandle(hThread1); ::CloseHandle(hThread2); closesocket( sClient ); WSACleanup(); // 資源釋放 return 0; }
客戶端代碼client.c
// client.cpp : Defines the entry point for the console application. // #include <stdio.h> #include <Winsock2.h> //Socket的函數調用 #include <windows.h> #define BUF_SIZE 6400 #pragma comment (lib, "ws2_32") // 使用WINSOCK2.H時,則需要庫文件WS2_32.LIB DWORD WINAPI Rcv( LPVOID lpParam ) { SOCKET sHost = *(SOCKET*)lpParam; int retVal; char bufRecv[BUF_SIZE]; memset( bufRecv, 0, sizeof( bufRecv ) ); while(1) { retVal = recv( sHost, bufRecv, BUF_SIZE, 0 ); if ( retVal == SOCKET_ERROR ) { printf( "recive faild!\n" ); break; } else { printf( "收到服務器消息:%s\n", bufRecv ); } } return 0; } DWORD WINAPI Snd( LPVOID lpParam ) { SOCKET sHost = *(SOCKET*)lpParam; int retVal; char bufSend[BUF_SIZE]; memset( bufSend, 0, sizeof( bufSend ) ); while(1) { gets( bufSend ); retVal = send( sHost, bufSend, strlen(bufSend)+sizeof(char), 0 ); if ( retVal == SOCKET_ERROR ) { printf( "send faild!\n" ); break; } } return 0; } int main(int argc, char* argv[]) { WSADATA wsaData; if ( WSAStartup( MAKEWORD(2,2), &wsaData ) != 0 ) { printf( "Winsock load faild!\n" ); return 1; } // 服務器套接字 SOCKET sHost = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( sHost == INVALID_SOCKET ) { printf( "socket faild!\n" ); WSACleanup(); return -1; } SOCKADDR_IN servAddr; servAddr.sin_family = AF_INET; // 注意 當把客戶端程序發到別人的電腦時 此處IP需改為服務器所在電腦的IP servAddr.sin_addr.S_un.S_addr = inet_addr( "127.0.0.1" ); servAddr.sin_port = htons( 9999 ); // 連接服務器 if ( connect( sHost, (LPSOCKADDR)&servAddr, sizeof( servAddr ) ) == SOCKET_ERROR ) { printf( "connect faild!\n" ); closesocket(sHost); WSACleanup(); return -1; } printf("連接到服務器 IP:[%s],port:[%d]\n",inet_ntoa(servAddr.sin_addr),ntohs(servAddr.sin_port)); HANDLE hThread1, hThread2; DWORD dwThreadId1, dwThreadId2; hThread1 = ::CreateThread( NULL, NULL, Snd, (LPVOID)&sHost, 0, &dwThreadId1 ); hThread2 = ::CreateThread( NULL, NULL, Rcv, (LPVOID)&sHost, 0, &dwThreadId2 ); ::WaitForSingleObject( hThread1, INFINITE ); ::WaitForSingleObject( hThread2, INFINITE ); ::CloseHandle(hThread1); ::CloseHandle(hThread2); closesocket(sHost); WSACleanup(); return 0; }
截圖如下:編譯好后首先是啟動服務端(來監聽),然后再啟動客戶端