【20090917】C++培训日记-网络编程基础
rt = = 今天的内容是基础的TCP\UDP Socket,以及TCP下使用Select。
【TCP】服务端
////////////////////////////////////////////////////////////////////////// // CopyRight(c) 2009, YOYO, All Rights Reserved. // Author: LIN YiQian // Created: 2009/09/17 // Describe: TCP 服务端 ////////////////////////////////////////////////////////////////////////// #include <WinSock2.h> #include <iostream> #pragma comment(lib, "ws2_32.lib") void main(void) { WORD wVersionRequired; WSADATA wsaData; wVersionRequired = MAKEWORD(1, 1); // 副版本号在前 主版本号在后 int nErr = WSAStartup(wVersionRequired, &wsaData); if (nErr != 0) { return; } if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) // 版本错误 { WSACleanup(); return; } SOCKET socketServer = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrServer; addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // 使用任意网卡上的IP地址 addrServer.sin_port = htons(9989); // 使用端口号 addrServer.sin_family = AF_INET; bind(socketServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)); listen(socketServer, 5); SOCKET socketClient; SOCKADDR_IN addrClient; int nLen = sizeof(SOCKADDR); while (true) { socketClient = accept(socketServer, (SOCKADDR*)&addrClient, &nLen); char szSendMsg[100]; sprintf(szSendMsg, "Welcome %s to ND.\n", inet_ntoa(addrClient.sin_addr)); send(socketClient, szSendMsg, strlen(szSendMsg) + 1, 0); char szRecvMsg[100]; recv(socketClient, szRecvMsg, 100, 0); std::cout << szRecvMsg << std::endl; closesocket(socketClient); } closesocket(socketServer); WSACleanup(); return; }
【TCP】客户端
////////////////////////////////////////////////////////////////////////// // CopyRight(c) 2009, YOYO, All Rights Reserved. // Author: LIN YiQian // Created: 2009/09/17 // Describe: TCP 客户端 ////////////////////////////////////////////////////////////////////////// #include <Winsock2.h> #include <iostream> #pragma comment(lib, "ws2_32.lib") void main(void) { WORD wVersionRequired; WSADATA wsaData; wVersionRequired = MAKEWORD(1, 1); int nErr = WSAStartup(wVersionRequired, &wsaData); if (nErr != 0) { return; } if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return; } SOCKET socketClient = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrServer; addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); addrServer.sin_port = htons(9989); addrServer.sin_family = AF_INET; connect(socketClient, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)); char szRecvMsg[100]; recv(socketClient, szRecvMsg, 100, 0); std::cout << szRecvMsg << std::endl; char szSendMsg[100]; sprintf(szSendMsg, "Re from Client..\n"); send(socketClient, szSendMsg, strlen(szSendMsg) + 1, 0); closesocket(socketClient); WSACleanup(); system("pause"); return; }
【UDP】服务端
////////////////////////////////////////////////////////////////////////// // CopyRight(c) 2009, YOYO, All Rights Reserved. // Author: LIN YiQian // Created: 2009/09/17 // Describe: UDP 服务端 ////////////////////////////////////////////////////////////////////////// #include <WinSock2.h> #include <iostream> #pragma comment(lib, "ws2_32.lib") void main(void) { WORD wVersionRequired; WSAData wsaData; wVersionRequired = MAKEWORD(1, 1); int nErr = WSAStartup(wVersionRequired, &wsaData); if (nErr != 0) { return; } if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return; } SOCKET socketServer = socket(AF_INET, SOCK_DGRAM, 0); SOCKADDR_IN addrServer; addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY); addrServer.sin_port = htons(9989); addrServer.sin_family = AF_INET; bind(socketServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)); SOCKADDR_IN addrClient; int nLen = sizeof(SOCKADDR); while (true) { char szRecvMsg[100]; recvfrom(socketServer, szRecvMsg, 100, 0, (SOCKADDR*)&addrClient, &nLen); std::cout << szRecvMsg << std::endl; } closesocket(socketServer); WSACleanup(); system("pause"); return; }
【UDP】客户端
////////////////////////////////////////////////////////////////////////// // CopyRight(c) 2009, YOYO, All Rights Reserved. // Author: LIN YiQian // Created: 2009/09/17 // Describe: UDP 客户端 ////////////////////////////////////////////////////////////////////////// #include <WinSock2.h> #include <iostream> #pragma comment(lib, "ws2_32.lib") void main(void) { WORD wVersionRequired; WSADATA wsaData; wVersionRequired = MAKEWORD(1, 1); int nErr = WSAStartup(wVersionRequired, &wsaData); if (nErr != 0) { return; } if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return; } SOCKET socketClient = socket(AF_INET, SOCK_DGRAM, 0); SOCKADDR_IN addrServer; addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); addrServer.sin_port = htons(9989); addrServer.sin_family = AF_INET; char szSendMsg[100]; sprintf(szSendMsg, "Connect Client!..\n"); sendto(socketClient, szSendMsg, strlen(szSendMsg) + 1, 0, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)); closesocket(socketClient); WSACleanup(); system("pause"); return; }
【TCP】使用Select-服务端
////////////////////////////////////////////////////////////////////////// // CopyRight(c) 2009, YOYO, All Rights Reserved. // Author: LIN YiQian // Created: 2009/09/17 // Describe: TCP Select 服务端 ////////////////////////////////////////////////////////////////////////// #include <WinSock2.h> #include <iostream> #include <set> #pragma comment(lib, "ws2_32.lib") typedef std::set<SOCKET> SOCKET_SET; void main(void) { WSADATA wsaData; if (WSAStartup( MAKEWORD(2, 2), &wsaData) != 0) { return; } if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { WSACleanup(); return; } SOCKET socketServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); SOCKADDR_IN addrServer; addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY); addrServer.sin_port = htons(9989); addrServer.sin_family = AF_INET; bind(socketServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)); listen(socketServer, 4); SOCKET socketClient; struct fd_set fdRead; int nSize; SOCKET_SET setSockets; char szMsg[128]; ZeroMemory(szMsg, sizeof(szMsg)); int nBlockMilli = 0; struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 100; while (true) { FD_ZERO(&fdRead); // 初始化fd_set FD_SET(socketServer, &fdRead); // 分配套接字句柄到对应的fd_set select(FD_SETSIZE, &fdRead, NULL, NULL, &timeout); nSize = sizeof(addrServer); if (FD_ISSET(socketServer, &fdRead)) // 如果套接字句柄还在fd_set里,说明 // 客户端已有connect的请求,马上就可以accept { socketClient = accept(socketServer, (SOCKADDR*)&addrServer, &nSize); setSockets.insert(socketClient); } FD_ZERO(&fdRead); for (SOCKET_SET::iterator iterSet = setSockets.begin(); iterSet != setSockets.end(); iterSet++) { FD_SET(*iterSet, &fdRead); } select(FD_SETSIZE, &fdRead, NULL, NULL, &timeout); for (SOCKET_SET::iterator iterSet = setSockets.begin(); iterSet != setSockets.end(); iterSet++) { if (FD_ISSET(*iterSet, &fdRead)) { recv(*iterSet, szMsg, strlen(szMsg) + 1, 0); std::cout << szMsg << std::endl; } } } for (SOCKET_SET::iterator iterSet = setSockets.begin(); iterSet != setSockets.end(); iterSet++) { closesocket(*iterSet); } closesocket(socketServer); WSACleanup(); return; }
【TCP】使用Select-客户端
////////////////////////////////////////////////////////////////////////// // CopyRight(c) 2009, YOYO, All Rights Reserved. // Author: LIN YiQian // Created: 2009/09/17 // Describe: TCP Select 客户端 ////////////////////////////////////////////////////////////////////////// #include <WinSock2.h> #include <iostream> #include <ctime> #pragma comment(lib, "ws2_32.lib") DWORD WINAPI ClientSocketThread(LPVOID lpParameter); void main(void) { WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { return; } if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { WSACleanup(); return; } SYSTEM_INFO systemInfo; GetSystemInfo(&systemInfo); // 开启CPU个数2倍的线程 for (int i = 0; i < (systemInfo.dwNumberOfProcessors * 2); ++i) { HANDLE handle = CreateThread(NULL, 0, ClientSocketThread, NULL, 0, NULL); if (handle == NULL) { std::cout << "创建Client线程失败!" << std::endl; } CloseHandle(handle); } while (true) { } WSACleanup(); return; } DWORD WINAPI ClientSocketThread(LPVOID lpParameter) { SOCKET socketClient = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrServer; addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); addrServer.sin_port = htons(9989); addrServer.sin_family = AF_INET; connect(socketClient, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)); char szMsg[100]; srand(time(NULL)); while (true) { sprintf(szMsg, "Socket %d connect..\n", socketClient); send(socketClient, szMsg, strlen(szMsg) + 1, 0); Sleep(100); } closesocket(socketClient); }