实现简单的Socket通信案例(个人尝试)
服务端代码(Server)
#include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.lib") #define PORT 9999 int main() { WSADATA WSAData; SOCKET sock, msgsock; struct sockaddr_in ServerAddr; if (WSAStartup(MAKEWORD(2, 0), &WSAData) != SOCKET_ERROR) { ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(PORT); ServerAddr.sin_addr.s_addr = INADDR_ANY; sock = socket(AF_INET, SOCK_STREAM, 0); int BindRet = bind(sock, (LPSOCKADDR)&ServerAddr, sizeof(ServerAddr)); int LinsRet = listen(sock, 10); printf("------------------------------------------------------------------------------------------ "); printf("绑定状态: %d 侦听状态: %d 绑定端口: %d ", BindRet, LinsRet, ntohs(ServerAddr.sin_port)); printf("------------------------------------------------------------------------------------------ "); } while (1) { char buf[1024]; msgsock = accept(sock, (LPSOCKADDR)0, (int *)0); memset(buf, 0, sizeof(buf)); recv(msgsock, buf, 1024, 0); printf("客户IP: %s 端口:%d 数据:%s ", inet_ntoa(ServerAddr.sin_addr), htons(ServerAddr.sin_port),buf); if (!strcmp(buf, "Success")) { printf("客户端已就绪... "); } closesocket(msgsock); } closesocket(sock); WSACleanup(); return 0; }
客户端代码(Client)
#include <winsock2.h> #include <stdio.h> #pragma comment(lib,"ws2_32.lib") #define IP "127.0.0.1" #define PORT 9999 //#ifdef _MSC_VER //#pragma comment( linker, "/subsystem:"windows" /entry:"mainCRTStartup"" ) //#endif int main() { while (1) { WSADATA WSAData; SOCKET sock; struct sockaddr_in ClientAddr; if (WSAStartup(MAKEWORD(2, 0), &WSAData) != SOCKET_ERROR) { ClientAddr.sin_family = AF_INET; //指Internet域 ClientAddr.sin_port = htons(PORT); //指定服务端所预留的端口 ClientAddr.sin_addr.s_addr = inet_addr(IP); //指定服务端所绑定的IP地址 sock = socket(AF_INET, SOCK_STREAM, 0); int Ret = connect(sock, (LPSOCKADDR)&ClientAddr, sizeof(ClientAddr)); if (Ret == 0) { char Status[] = "Success"; int ServerRet = send(sock, Status, sizeof(Status), 0); if (ServerRet != 0) { printf("发送给服务器Success状态成功.. "); } } } closesocket(sock); WSACleanup(); Sleep(5000); } return 0; }
实现Socket单工通信案例
服务端代码(Server)
#include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.lib") //把ws2_32.lib加到Link页的连接库 #define PORT 15001 //通信的端口(指服务器端) #define ERROR 0 #define BUFFER_SIZE 1024 //注意:此Server端数据接收缓冲区 >= Client端数据发送缓冲区 ,否则造成缓冲区溢出 /* 服务端原理: 1、服务器进程创建套接字 2、将本地地址绑定到所创建的套接字上,以三元组{<通信协议>,<IP地址>,<端口号>}在网络上标识该套接字 3、将套接字置入监听模式,并准备接受连接请求 */ int main() { WSADATA WSAData; if(WSAStartup(MAKEWORD(2,0),&WSAData)==SOCKET_ERROR) //启动winsock ,WSAStartup()函数对Winsock DLL进行初始化 { printf("Socket initialize fail! "); exit(1); } SOCKET sock; //服务进程创建套接字句柄(用于监听) if((sock=socket(AF_INET,SOCK_STREAM,0))==ERROR) //调用socket()函数创建一个流套接字,参数(网络地址类型,套接字类型,网络协议) { printf("Socket create! "); WSACleanup(); exit(1); } struct sockaddr_in ServerAddr; //sockaddr_in结构用来标识TCP/IP协议下的地址,可强制转换为sockaddr结构 ServerAddr.sin_family=AF_INET; //sin_family字段必须设为AF_INET,表示该Socket处于Internet域 ServerAddr.sin_port=htons(PORT); //sin_port字段用于指定服务端口,注意避免冲突 ServerAddr.sin_addr.s_addr=INADDR_ANY; //sin_addr字段用于把一个IP地址保存为一个4字节的数,无符号长整型,根据不同用法还可表示本地或远程IP地址 if(bind(sock,(LPSOCKADDR)&ServerAddr,sizeof(ServerAddr))==SOCKET_ERROR) //调用bind()函数将本地地址绑定到所创建的套接字上,以在网络上标识该套接字 { printf("Bind fail! "); closesocket(sock); WSACleanup(); exit(1); } printf("Server Socket Port:%d ",ntohs(ServerAddr.sin_port)); if(listen(sock,10)==SOCKET_ERROR) //调用listen()函数将套接字置入监听模式并准备接受连接请求,参数(已捆绑未连接的套接字描述字,正在等待连接的最大队列长度) { printf("Listen fail! "); closesocket(sock); WSACleanup(); exit(1); } SOCKET msgsock; //创建一个新的套接字(用于接收accept函数的返回值,即表示已经接受的那个客户端的连接,进而接收Client发来的数据) char buf[BUFFER_SIZE]; //数据接收缓冲区 while(1) { if((msgsock=accept(sock,(LPSOCKADDR)0,(int *)0))==INVALID_SOCKET) //进入监听状态后,调用accept()函数接收客户端的连接请求,并把连接传给msgsock套接字,原sock套接字继续监听其他客户机连接请求 { printf("Accept fail! "); continue; } memset(buf,0,sizeof(buf)); //初始化数据接收缓冲区 recv(msgsock,buf,BUFFER_SIZE,0); //接收客户端发送过来的数据 if(buf[0]=='e' && buf[1]=='x' && buf[2]=='i' && buf[3]=='t') //"exit"命令,退出程序 { printf("The End. "); break; } printf("C:\Socket\Server>%s",buf); closesocket(msgsock); } closesocket(sock); //关闭套接字 WSACleanup(); //终止对Winsock DLL的使用,并释放资源 return 0; }
客户端代码(Client)
#include <winsock2.h> #include <stdio.h> #pragma comment(lib,"ws2_32.lib") //把ws2_32.lib加到Link页的连接库 //#define IP "172.18.68.243" //在两台计算机上测试,IP为Server端的IP地址 #define IP "127.0.0.1" //在一台计算机上测试,IP为本地回送地址 #define PORT 15001 //注意:客户端设置通信的端口 = 服务端的端口 #define BUFFER_SIZE 1024 //数据发送缓冲区大小 int main() { char buf[BUFFER_SIZE]; //buf数组存放客户端发送的消息 int inputLen; //用于输入字符自增变量 while(1) { printf("C:\Socket\Client>"); inputLen=0; memset(buf,0,sizeof(buf)); while((buf[inputLen++]=getchar())!=' ') //输入以回车键为结束标识 { ; } if(buf[0]=='e' && buf[1]=='x' && buf[2]=='i' && buf[3]=='t') { printf("The End. "); break; } WSADATA WSAData; if(WSAStartup(MAKEWORD(2,0),&WSAData)==SOCKET_ERROR) //WSAStartup()函数对Winsock DLL进行初始化 { printf("Socket initialize fail! "); continue; } SOCKET sock; //客户端进程创建套接字 if((sock=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR) //创建流套接字(与服务端保持一致) { printf("Socket create fail! "); WSACleanup(); continue; } struct sockaddr_in ClientAddr; //sockaddr_in结构用来标识TCP/IP协议下的地址,可强制转换为sockaddr结构 ClientAddr.sin_family=AF_INET; //指Internet域 ClientAddr.sin_port=htons(PORT); //指定服务端所预留的端口 ClientAddr.sin_addr.s_addr=inet_addr(IP); //指定服务端所绑定的IP地址 if(connect(sock,(LPSOCKADDR)&ClientAddr,sizeof(ClientAddr))==SOCKET_ERROR) //调用connect()函数,向服务器进程发出连接请求 { printf("Connect fail! "); closesocket(sock); WSACleanup(); continue; } send(sock,buf,BUFFER_SIZE,0); //向服务器发送数据 closesocket(sock); //关闭套接字 WSACleanup(); //终止对Winsock DLL的使用,并释放资源,以备下一次使用 } return 0; }
转载:https://blog.csdn.net/lynch0571
实现Socket双工通信案例
服务端代码(Server)
#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! "); break; } else { printf("收到客户端消息:%s ", 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! "); break; } } return 0; } int main(int argc, char* argv[]) { // 初始化套接字动态库 WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("winsock load faild! "); return 1; } // 创建服务段套接字 SOCKET sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sServer == INVALID_SOCKET) { printf("socket faild! "); 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! "); closesocket(sServer); WSACleanup(); return -1; } printf("Server is On IP:[%s],port:[%d] ", inet_ntoa(addrServ.sin_addr), ntohs(addrServ.sin_port)); // 监听套接字 数字表示最多能监听客户个数 if (listen(sServer, 5) == SOCKET_ERROR) { printf("listen faild! "); 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! "); closesocket(sServer); WSACleanup(); return -1; } printf("accepted client IP:[%s],port:[%d] ", 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)
#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! "); break; } else { printf("收到服务器消息:%s ", 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! "); break; } } return 0; } int main(int argc, char* argv[]) { WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("Winsock load faild! "); return 1; } // 服务器套接字 SOCKET sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sHost == INVALID_SOCKET) { printf("socket faild! "); 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! "); closesocket(sHost); WSACleanup(); return -1; } printf("连接到服务器 IP:[%s],port:[%d] ", 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; }
转载:https://www.cnblogs.com/wuyepeng/
实现文件传输
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <WinSock2.h> #define PORT 8087 #define SERVER_IP "127.0.0.1" #define BUFFER_SIZE 1024 #define FILE_NAME_MAX_SIZE 512 #pragma comment(lib, "WS2_32") int main() { // 声明并初始化一个服务端(本地)的地址结构 sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_addr.S_un.S_addr = INADDR_ANY; server_addr.sin_port = htons(PORT); // 初始化socket dll WSADATA wsaData; WORD socketVersion = MAKEWORD(2, 0); if (WSAStartup(socketVersion, &wsaData) != 0) { printf("Init socket dll error!"); exit(1); } // 创建socket SOCKET m_Socket = socket(AF_INET, SOCK_STREAM, 0); if (SOCKET_ERROR == m_Socket) { printf("Create Socket Error!"); exit(1); } //绑定socket和服务端(本地)地址 if (SOCKET_ERROR == bind(m_Socket, (LPSOCKADDR)&server_addr, sizeof(server_addr))) { printf("Server Bind Failed: %d", WSAGetLastError()); exit(1); } //监听 if (SOCKET_ERROR == listen(m_Socket, 10)) { printf("Server Listen Failed: %d", WSAGetLastError()); exit(1); } while (1) { printf("Listening To Client... "); sockaddr_in client_addr; int client_addr_len = sizeof(client_addr); SOCKET m_New_Socket = accept(m_Socket, (sockaddr *)&client_addr, &client_addr_len); if (SOCKET_ERROR == m_New_Socket) { printf("Server Accept Failed: %d", WSAGetLastError()); break; } char buffer[BUFFER_SIZE]; memset(buffer, 0, BUFFER_SIZE); if (recv(m_New_Socket, buffer, BUFFER_SIZE, 0) < 0) { printf("Server Receive Data Failed!"); break; } char file_name[FILE_NAME_MAX_SIZE + 1]; memset(file_name, 0, FILE_NAME_MAX_SIZE + 1); strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer)); printf("%s ", file_name); FILE * fp = fopen(file_name, "rb"); //windows下是"rb",表示打开一个只读的二进制文件 if (NULL == fp) { printf("File: %s Not Found ", file_name); } else { memset(buffer, 0, BUFFER_SIZE); int length = 0; while ((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0) { if (send(m_New_Socket, buffer, length, 0) < 0) { printf("Send File: %s Failed ", file_name); break; } memset(buffer, 0, BUFFER_SIZE); } fclose(fp); printf("File: %s Transfer Successful! ", file_name); } closesocket(m_New_Socket); } closesocket(m_Socket); //释放winsock库 WSACleanup(); return 0; }
/************************************************************************* > File Name: Win_Client.c > Author: SongLee ************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <WinSock2.h> #define PORT 8087 #define SERVER_IP "127.0.0.1" #define BUFFER_SIZE 1024 #define FILE_NAME_MAX_SIZE 512 #pragma comment(lib, "WS2_32") int main() { // 初始化socket dll WSADATA wsaData; WORD socketVersion = MAKEWORD(2, 0); if (WSAStartup(socketVersion, &wsaData) != 0) { printf("Init socket dll error!"); exit(1); } //创建socket SOCKET c_Socket = socket(AF_INET, SOCK_STREAM, 0); if (SOCKET_ERROR == c_Socket) { printf("Create Socket Error!"); system("pause"); exit(1); } //指定服务端的地址 sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_addr.S_un.S_addr = inet_addr(SERVER_IP); server_addr.sin_port = htons(PORT); if (SOCKET_ERROR == connect(c_Socket, (LPSOCKADDR)&server_addr, sizeof(server_addr))) { printf("Can Not Connect To Server IP! "); system("pause"); exit(1); } //输入文件名 char file_name[FILE_NAME_MAX_SIZE + 1]; memset(file_name, 0, FILE_NAME_MAX_SIZE + 1); printf("Please Input File Name On Server: "); scanf("%s", &file_name); char buffer[BUFFER_SIZE]; memset(buffer, 0, BUFFER_SIZE); strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name)); //向服务器发送文件名 if (send(c_Socket, buffer, BUFFER_SIZE, 0) < 0) { printf("Send File Name Failed "); system("pause"); exit(1); } //打开文件,准备写入 FILE * fp = fopen(file_name, "wb"); //windows下是"wb",表示打开一个只写的二进制文件 if (NULL == fp) { printf("File: %s Can Not Open To Write ", file_name); system("pause"); exit(1); } else { memset(buffer, 0, BUFFER_SIZE); int length = 0; while ((length = recv(c_Socket, buffer, BUFFER_SIZE, 0)) > 0) { if (fwrite(buffer, sizeof(char), length, fp) < length) { printf("File: %s Write Failed ", file_name); break; } memset(buffer, 0, BUFFER_SIZE); } printf("Receive File: %s From Server Successful! ", file_name); } fclose(fp); closesocket(c_Socket); //释放winsock库 WSACleanup(); system("pause"); return 0; }
转载:脚本之家
使用select
#include<stdlib.h> #include<WINSOCK2.H> #include <windows.h> #include <process.h> #include<iostream> #include<string> using namespace std; #define BUF_SIZE 64 #pragma comment(lib,"WS2_32.lib") void recv(PVOID pt) { SOCKET sHost = *((SOCKET *)pt); while (true) { char buf[BUF_SIZE];//清空接收数据的缓冲区 memset(buf, 0, BUF_SIZE); int retVal = recv(sHost, buf, sizeof(buf), 0); if (SOCKET_ERROR == retVal) { int err = WSAGetLastError(); //无法立即完成非阻塞Socket上的操作 if (err == WSAEWOULDBLOCK) { Sleep(1000); printf(" waiting reply!"); continue; } else if (err == WSAETIMEDOUT || err == WSAENETDOWN || err == WSAECONNRESET)//已建立连接 { printf(" recv failed!"); closesocket(sHost); WSACleanup(); return; } } Sleep(100); printf(" %s", buf); //break; } } int main() { WSADATA wsd; SOCKET sHost; SOCKADDR_IN servAddr;//服务器地址 int retVal;//调用Socket函数的返回值 char buf[BUF_SIZE]; //初始化Socket环境 if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) { printf("WSAStartup failed! "); return -1; } sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //设置服务器Socket地址 servAddr.sin_family = AF_INET; servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //在实际应用中,建议将服务器的IP地址和端口号保存在配置文件中 servAddr.sin_port = htons(6000); //计算地址的长度 int sServerAddlen = sizeof(servAddr); //调用ioctlsocket()将其设置为非阻塞模式 int iMode = 1; retVal = ioctlsocket(sHost, FIONBIO, (u_long FAR*)&iMode); if (retVal == SOCKET_ERROR) { printf("ioctlsocket failed!"); WSACleanup(); return -1; } //循环等待 while (true) { //连接到服务器 retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr)); if (SOCKET_ERROR == retVal) { int err = WSAGetLastError(); //无法立即完成非阻塞Socket上的操作 if (err == WSAEWOULDBLOCK || err == WSAEINVAL) { Sleep(1); printf("check connect! "); continue; } else if (err == WSAEISCONN)//已建立连接 { break; } else { printf("connection failed! "); closesocket(sHost); WSACleanup(); return -1; } } } unsigned long threadId = _beginthread(recv, 0, &sHost);//启动一个线程接收数据的线程 while (true) { //向服务器发送字符串,并显示反馈信息 printf("input a string to send: "); std::string str; //接收输入的数据 std::cin >> str; //将用户输入的数据复制到buf中 ZeroMemory(buf, BUF_SIZE); strcpy(buf, str.c_str()); if (strcmp(buf, "quit") == 0) { printf("quit! "); break; } while (true) { retVal = send(sHost, buf, strlen(buf), 0); if (SOCKET_ERROR == retVal) { int err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) { //无法立即完成非阻塞Socket上的操作 Sleep(5); continue; } else { printf("send failed! "); closesocket(sHost); WSACleanup(); return -1; } } break; } } return 0; }
#include <WinSock2.h> #include <Windows.h> #include <MSWSock.h> #include <stdio.h> #include <map> using namespace std; #pragma comment(lib,"Ws2_32.lib") #pragma comment(lib,"Mswsock.lib") int main() { WSAData wsaData; if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) { printf("初始化失败!%d ", WSAGetLastError()); Sleep(5000); return -1; } USHORT nport = 6000; SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); u_long ul = 1; ioctlsocket(sListen, FIONBIO, &ul); sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(nport); sin.sin_addr.S_un.S_addr = ADDR_ANY; if (SOCKET_ERROR == bind(sListen, (sockaddr*)&sin, sizeof(sin))) { printf("bind failed!%d ", WSAGetLastError()); Sleep(5000); return -1; } listen(sListen, 5); //1)初始化一个套接字集合fdSocket,并将监听套接字放入 fd_set socketSet; FD_ZERO(&socketSet); FD_SET(sListen, &socketSet); TIMEVAL time = { 1, 0 }; char buf[4096]; fd_set readSet; FD_ZERO(&readSet); fd_set writeSet; FD_ZERO(&readSet); while (true) { //2)将fdSocket的一个拷贝fdRead传给select函数 readSet = socketSet; writeSet = socketSet; //同时检查套接字的可读可写性。 int nRetAll = select(0, &readSet, &writeSet, NULL, NULL/*&time*/);//若不设置超时则select为阻塞 if (nRetAll >0) //-1 { //是否存在客户端的连接请求。 if (FD_ISSET(sListen, &readSet))//在readset中会返回已经调用过listen的套接字。 { if (socketSet.fd_count < FD_SETSIZE) { sockaddr_in addrRemote; int nAddrLen = sizeof(addrRemote); SOCKET sClient = accept(sListen, (sockaddr*)&addrRemote, &nAddrLen); if (sClient != INVALID_SOCKET) { FD_SET(sClient, &socketSet); printf(" 接收到连接:(%s)", inet_ntoa(addrRemote.sin_addr)); } } else { printf("连接数量已达上限! "); continue; } } for (int i = 0; i<socketSet.fd_count; i++) { if (FD_ISSET(socketSet.fd_array[i], &readSet)) { //调用recv,接收数据。 int nRecv = recv(socketSet.fd_array[i], buf, 4096, 0); if (nRecv > 0) { buf[nRecv] = 0; printf(" recv %d : %s", socketSet.fd_array[i], buf); } } if (FD_ISSET(socketSet.fd_array[i], &writeSet)) { //调用send,发送数据。 char buf[] = "hello!"; int nRet = send(socketSet.fd_array[i], buf, strlen(buf) + 1, 0); if (nRet <= 0) { if (GetLastError() == WSAEWOULDBLOCK) { //do nothing } else { closesocket(socketSet.fd_array[i]); FD_CLR(socketSet.fd_array[i], &socketSet); } } else { printf(" send hello!"); } } } } else if (nRetAll == 0) { printf("time out! "); } else { printf("select error!%d ", WSAGetLastError()); Sleep(5000); break; } Sleep(1000); } closesocket(sListen); WSACleanup(); }