Windows Socket編程TCP範例之二(select)

來源:互聯網
上載者:User
通過select模型,可以在多個用戶端串連的情況下,無需建立多個線程處理即單線程處理。以下樣本:Client端向Server端發送資料,Server端接收資料並輸出。

Server.cpp

#include <iostream>#include <windows.h>using namespace std;#pragma comment(lib, "Ws2_32.lib")#define PORT_NO 6000#define BACKLOG 10int main(int argc, char* argv[]){WSADATA wsaData;int ret;WORD wVersionRequested = MAKEWORD(2, 2);SOCKET sockSrv;SOCKADDR_IN addrSrv, addrClient;HANDLE hThread = NULL;// 初始化Windows Socket------ret = WSAStartup(wVersionRequested, &wsaData);if (ret != 0) {cout << "WSAStartup() failed:" << WSAGetLastError() << endl;return -1;}// 建立Socket------sockSrv = socket(AF_INET, SOCK_STREAM, 0);if (INVALID_SOCKET == sockSrv){cout << "socket() failed:" << WSAGetLastError() << endl;WSACleanup();return -1;}addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);addrSrv.sin_family = AF_INET;addrSrv.sin_port = htons(PORT_NO);// Bind Socket------ret = bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));if (SOCKET_ERROR == ret){cout << "bind() failed:" << WSAGetLastError() << endl;closesocket(sockSrv);WSACleanup();return -1;}// 監聽------ret = listen(sockSrv, BACKLOG);if (SOCKET_ERROR == ret){cout << "listen() failed:" << WSAGetLastError() << endl;closesocket(sockSrv);WSACleanup();return -1;}cout<< "Server started......" << endl;// select------//單線程實現多用戶端處理fd_set fdSocketAll;   // 記錄所有socketFD_ZERO(&fdSocketAll); FD_SET(sockSrv, &fdSocketAll);while (1){fd_set fdRead = fdSocketAll;ret = select(0, &fdRead, NULL, NULL, NULL);if (0 == ret)  // 逾時,由於timeout設為NULL,所有沒有逾時之說{cout << "over time..." << endl;continue;}else if (ret > 0)// ok{#pragma regionfor (int i=0; i<(int)fdRead.fd_count; ++i){SOCKET sock = fdRead.fd_array[i];if (sock == sockSrv)// 監聽通訊端接受到新串連{int len=sizeof(SOCKADDR);SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);if (INVALID_SOCKET == sockConn){cout << "accept() failed:" << WSAGetLastError() << endl;break;}cout << "接受到新串連:" << ::inet_ntoa(addrClient.sin_addr) << endl;if (fdSocketAll.fd_count < FD_SETSIZE){FD_SET(sockConn, &fdSocketAll);}else{cout << "Too much connections!" << endl;closesocket(sockConn);}}else    // 有資料可讀取{char recvBuffer[MAX_PATH] = {0};ret = recv(sock, recvBuffer, sizeof(recvBuffer), 0);if (ret == 0){cout << "Connection has been gracefully closed." << endl;FD_CLR(sock, &fdSocketAll);closesocket(sock);continue;}else if (ret == SOCKET_ERROR) {cout << "Connection has been closed ungracefully." << endl;FD_CLR(sock, &fdSocketAll);closesocket(sock);continue;}cout << "Receive Data from Client:" << recvBuffer << endl;}}#pragma endregion}else// error{cout << "select() failed:" << WSAGetLastError() << endl;break;}}// 清理資源------for (int i=0; i<(int)fdSocketAll.fd_count; ++i){closesocket(fdSocketAll.fd_array[i]);}WSACleanup();cout << "exit..." << endl;return 0;}

Client.cpp

#include <iostream>#include <windows.h>using namespace std;#pragma comment(lib, "Ws2_32.lib")#define PORT_NO 6000#define SRV_IP_ADDR "127.0.0.1"int main(int argc, char* argv[]){int ret;WSADATA wsaData;WORD wVersionRequested = MAKEWORD(2, 2);SOCKET sockClient;SOCKADDR_IN addrSrv;// 初始化Windows Socket------ret = WSAStartup(wVersionRequested, &wsaData);if (ret != 0) {cout << "WSAStartup() failed:" << WSAGetLastError() << endl;return -1;}    // 建立Socket------sockClient = socket(AF_INET, SOCK_STREAM, 0);if (INVALID_SOCKET == sockClient){cout << "socket() failed:" << WSAGetLastError() << endl;WSACleanup();return -1;}addrSrv.sin_addr.S_un.S_addr = inet_addr(SRV_IP_ADDR);addrSrv.sin_family = AF_INET;addrSrv.sin_port = htons(PORT_NO);// 串連------ret = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));if (SOCKET_ERROR == ret){cout << "connect() failed:" << WSAGetLastError() << endl;closesocket(sockClient);WSACleanup();return -1;}else{cout << "connect() successfully." << endl;}// 發送資料------char sendBuf[MAX_PATH] = {0};while (1){cin.getline(sendBuf, sizeof(sendBuf));if (strcmp(sendBuf, "exit") == 0){break;}ret = send(sockClient, sendBuf, strlen(sendBuf)+1, 0);if (SOCKET_ERROR == ret){cout << "send() failed:" << WSAGetLastError() << endl;closesocket(sockClient);WSACleanup();return -1;}}// 清理資源-------closesocket(sockClient);WSACleanup();cout << "exit..." << endl;return 0;}

片如下:

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.