实现功能
客户端向服务端发送消息。服务端收到消息后,向客户端发送应答消息。客户端接收应答消息,并显示出来。
程序设计简图
代码实现
服务器端代码(操作系统XP 编译器VS2010)
main.cpp
#include <Windows.h> #include <iostream> #pragma comment(lib, "ws2_32.lib") bool StartUp() { //<此段代码源于MSDN> WORD wVersionRequested; WSADATA wsaData; int err; //Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { //Tell the user that we could not find a usable Winsock DLL. printf("WSAStartup failed with error: %d\n", err); return false; } //Confirm that the WinSock DLL supports 2.2. //Note that if the DLL supports versions greater //than 2.2 in addition to 2.2, it will still return //2.2 in wVersion since that is the version we requested. if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { //Tell the user that we could not find a usable WinSock DLL. printf("Could not find a usable version of Winsock.dll\n"); WSACleanup(); return false; } else printf("The Winsock 2.2 dll was found okay\n"); //The Winsock DLL is acceptable. Proceed to use it //Add network programming using Winsock here //then call WSACleanup when done using the Winsock dll //WSACleanup(); //</此段代码源于MSDN> return true; } bool SetupServer(); int main() { StartUp(); SetupServer(); WSACleanup(); std::cin.get(); return 0; }
test.cpp
#include <Windows.h> #include <iostream> #define DEFAULT_BUFLEN 512 bool CreateSocket(SOCKET & sockOut); bool BinSocket(SOCKET sock); void Serve(SOCKET clientSocket); bool SetupServer() { SOCKET sock = INVALID_SOCKET; if(!CreateSocket(sock)) return false; if(!BinSocket(sock)) return false; if(listen(sock, SOMAXCONN) == SOCKET_ERROR) { printf("Listen failed with error: %ld\n", WSAGetLastError()); return false; } SOCKET clientSocket = INVALID_SOCKET; // Accept a client socket clientSocket = accept(sock, NULL, NULL); if (clientSocket == INVALID_SOCKET) { printf("accept failed: %d\n", WSAGetLastError()); return false; } Serve(clientSocket); closesocket(sock); return true; } bool CreateSocket(SOCKET & sockOut) { int iFamily = AF_INET; int iType = SOCK_STREAM; //tcp连接 int iProtocol = IPPROTO_TCP; int iResult = 0; sockOut = socket(iFamily, iType, iProtocol); if (sockOut == INVALID_SOCKET) { wprintf(L"socket function failed with error = %d\n", WSAGetLastError() ); return false; } else { wprintf(L"socket function succeeded\n"); } return true; } bool BinSocket(SOCKET sock) { // The socket address to be passed to bind sockaddr_in service; service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr("192.168.1.102"); //服务器IP service.sin_port = htons(27015); //要使用的端口号 // Bind the socket. int iResult = bind(sock, (SOCKADDR *) &service, sizeof (service)); if (iResult == SOCKET_ERROR) { wprintf(L"bind failed with error %u\n", WSAGetLastError()); closesocket(sock); return false; } else wprintf(L"bind returned success\n"); return true; } void Serve(SOCKET clientSocket) { const char * revInfo = "received"; char recvbuf[DEFAULT_BUFLEN]; int recvbuflen = DEFAULT_BUFLEN; int iResult = 0; do { iResult = recv(clientSocket, recvbuf, recvbuflen, 0); if (iResult > 0) { recvbuf[iResult]='\0'; printf("Bytes received: %d\n", iResult); printf("context from client %s", recvbuf); send(clientSocket, revInfo, strlen(revInfo), 0); } else if (iResult == 0) printf("Connection closing...\n"); else { printf("recv failed: %d\n", WSAGetLastError()); return ; } }while (iResult > 0); }
客户端代码(操作系统Win7专业版 编译器VS2010)
main.cpp
#include <WinSock2.h> #include <iostream> #define DEFAULT_BUFLEN 512 #pragma comment(lib, "ws2_32.lib") bool StartUp() { //<此段代码源于MSDN> WORD wVersionRequested; WSADATA wsaData; int err; //Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { //Tell the user that we could not find a usable Winsock DLL. printf("WSAStartup failed with error: %d\n", err); return false; } //Confirm that the Wup when done using the Winsock dll //WSACleanup(); //</此段代码源于MSDN> return true; } bool SetupServer(); int main() { StartUp(); SOCKET connectSocket = INVALID_SOCKET; //struct addrinfo * l; char * sendbuf = "this is test"; char recvbuf[DEFAULT_BUFLEN]; int recvbuflen = DEFAULT_BUFLEN; struct addrinfo hints; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; connectSocket = socket(AF_INET,SOCK_STREAM,0); if(IPPROTO_TCP == INVALID_SOCKET) { printf("socket failed with error:ld\n", WSAGetLastError()); return 0; } sockaddr_in service; memset(&service, 0, sizeof(sockaddr_in)); service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr("192.168.1.102"); service.sin_port = htons(27015); int iResult = connect(connectSocket, (const sockaddr*)&service, sizeof(sockaddr)); if(iResult == SOCKET_ERROR) { wprintf(L"connnect function failed with error:%ld\n", WSAGetLastError()); switch(WSAGetLastError()) { case WSAECONNREFUSED: wprintf(L"No connection could be made because the target machine actively refused it"); break; } return 0; } //ZeroMemory(&hints, sizeof(hints)); iResult = send(connectSocket, sendbuf, (int)strlen(sendbuf), 0); if(iResult == SOCKET_ERROR) { printf("send failed"); return 0; } iResult = recv(connectSocket, recvbuf, recvbuflen, 0); if(iResult==0) printf("Connection closed\n"); else if(iResult <0) printf("rev failed"); else { recvbuf[iResult] = '\0'; printf("Recieve from server:%s", recvbuf); } WSACleanup(); std::cin.get(); return 0; }
函数解释参见MSDN