使用C++实现Win32平台的TCP/IP网络编程,练习socket的使用。
服务端:
#include <iostream> #include <WinSock2.h> const unsigned short LISTEN_PORT = 8700; int main(int argc, char* argv[]) { using namespace std; WORD wVersionRequested = MAKEWORD(1, 1); WSADATA wsaData; int err = WSAStartup(wVersionRequested, &wsaData); if ( 0 != err ) { cout<<"WSAStartup failed. return: "<<err<<endl; return -1; } if ( wsaData.wVersion != wVersionRequested ) { cout<<"wsaData.wVersion: "<<wsaData.wVersion<<" is not equal to wVersionRequested: "<<wVersionRequested<<endl; WSACleanup(); return -2; } SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); if ( INVALID_SOCKET == sock ) { cout<<"socket error: "<<WSAGetLastError()<<endl; return -3; } SOCKADDR_IN addr_server; addr_server.sin_family = AF_INET; addr_server.sin_port = htons(LISTEN_PORT); addr_server.sin_addr.S_un.S_addr = htonl(INADDR_ANY); err = bind(sock, (SOCKADDR*)&addr_server, sizeof(addr_server)); if ( SOCKET_ERROR == err ) { cout<<"bind error: "<<WSAGetLastError()<<endl; return -4; } err = listen(sock, SOMAXCONN); if ( SOCKET_ERROR == err ) { cout<<"listen error: "<<WSAGetLastError()<<endl; return -5; } cout<<"Start listening on port "<<LISTEN_PORT<<endl; SOCKADDR_IN addr_client; int addrlen = sizeof(addr_client); while (true) { SOCKET sock_con = accept(sock, (SOCKADDR*)&addr_client, &addrlen); if ( INVALID_SOCKET != sock_con ) { cout<<inet_ntoa(addr_client.sin_addr)<<":"<<ntohs(addr_client.sin_port)<<" connected!"<<endl; char recv_buf[256]; char send_buf[512]; while (true) { err = recv(sock_con, recv_buf, sizeof(recv_buf), 0); if ( err <= 0 ) { cout<<"recv error: "<<WSAGetLastError()<<endl; break; } sprintf(send_buf, "%s:%d said: %s", inet_ntoa(addr_client.sin_addr), ntohs(addr_client.sin_port), recv_buf); cout<<send_buf<<endl; sprintf(send_buf, "you said: %s", recv_buf); err = send(sock_con, send_buf, strlen(send_buf) + 1, 0); if ( SOCKET_ERROR == err ) { cout<<"send error: "<<WSAGetLastError()<<endl; break; } } cout<<inet_ntoa(addr_client.sin_addr)<<":"<<ntohs(addr_client.sin_port)<<" left!"<<endl; err = closesocket(sock_con); if ( SOCKET_ERROR == err ) { cout<<"closesocket error: "<<WSAGetLastError()<<endl; } } else { cout<<"accept error: "<<WSAGetLastError()<<endl; } } WSACleanup(); return 0; }
客户端:
#include <iostream> #include <WinSock2.h> const char* SERVER_IP = "127.0.0.1"; const unsigned short SERVER_PORT = 8700; int main(int argc, char* argv[]) { using namespace std; WORD wVersionRequested = MAKEWORD(1, 1); WSADATA wsaData; int err = WSAStartup(wVersionRequested, &wsaData); if ( 0 != err ) { cout<<"WSAStartup failed. return: "<<err<<endl; return -1; } if ( wsaData.wVersion != wVersionRequested ) { cout<<"wsaData.wVersion: "<<wsaData.wVersion<<" is not equal to wVersionRequested: "<<wVersionRequested<<endl; WSACleanup(); return -2; } SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); if ( INVALID_SOCKET == sock ) { cout<<"socket error: "<<WSAGetLastError()<<endl; return -3; } SOCKADDR_IN addr_server; addr_server.sin_family = AF_INET; addr_server.sin_port = htons(SERVER_PORT); addr_server.sin_addr.S_un.S_addr = inet_addr(SERVER_IP); err = connect(sock, (SOCKADDR*)&addr_server, sizeof(addr_server)); if ( SOCKET_ERROR == err ) { cout<<"connect error: "<<WSAGetLastError()<<endl; return -4; } cout<<"Connection established."<<endl; char send_buf[256]; char recv_buf[512]; while (true) { cin.getline(send_buf, 256); cin.clear(); //NOTE: If not clear, when input size overflow, getline will fail the next time. if ( 0 == stricmp(send_buf, "quit") || 0 == stricmp(send_buf, "exit") ) break; err = send(sock, send_buf, strlen(send_buf) + 1, 0); if ( SOCKET_ERROR == err ) { cout<<"send error: "<<WSAGetLastError()<<endl; } err = recv(sock, recv_buf, sizeof(recv_buf), 0); if ( err <= 0 ) { cout<<"recv error: "<<WSAGetLastError()<<endl; } cout<<recv_buf<<endl; } err = closesocket(sock); if ( SOCKET_ERROR == err ) { cout<<"closesocket error: "<<WSAGetLastError()<<endl; } WSACleanup(); return 0; }