基于UDP的select函数用法

/************SERVER**************/ #include #include #define PORT_A 11111 #define PORT_B 22222 void main(int argc, char **argv) { WSADATA wsaData; // 套接口信息数据 SOCKET socka; // 套接口a SOCKET sockb; // 套接口b int nPortA = PORT_A; int nPortB = PORT_B; fd_set rfd; // 读描述符集 timeval timeout; // 定时变量 sockaddr_in addr; // 告诉sock 应该在什么地方licence char recv_buf[1024]; // 接收缓冲区 int nRecLen; // 客户端地址长度!!!!!! sockaddr_in cli; // 客户端地址 int nRet; // select返回值 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("failed to laod winsock!/n"); return; } socka = socket(AF_INET, SOCK_DGRAM, 0); // 创建数据报socka if (socka == INVALID_SOCKET) { printf("socket()/n"); return; } sockb = socket(AF_INET, SOCK_DGRAM, 0); // 创建数据报sockb if (sockb == INVALID_SOCKET) { printf("socket()/n"); return; } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; // IP协议 addr.sin_port = htons(nPortA); // 端口 addr.sin_addr.s_addr = htonl(INADDR_ANY); // 在本机的所有ip上开始监听 if (bind(socka, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)// bind socka { printf("bind()/n"); return; } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; // IP协议 addr.sin_port = htons(nPortB); // 端口 addr.sin_addr.s_addr = htonl(INADDR_ANY); // 在本机的所有ip上开始监听 if (bind(sockb, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) // bind sockb { printf("bind()/n"); return; } // 设置超时时间为6s timeout.tv_sec = 6; timeout.tv_usec = 0; memset(recv_buf, 0, sizeof(recv_buf)); // 清空接收缓冲区 while (true) { FD_ZERO(&rfd); // 在使用之前总是要清空 // 开始使用select FD_SET(socka, &rfd); // 把socka放入要测试的描述符集中 FD_SET(sockb, &rfd); // 把sockb放入要测试的描述符集中 nRet = select(0, &rfd, NULL, NULL, &timeout);// 检测是否有套接口是否可读 if (nRet == SOCKET_ERROR) { printf("select()/n"); return; } else if (nRet == 0) // 超时 { printf("timeout/n"); closesocket(socka); closesocket(sockb); break; } else // 检测到有套接口可读 { if (FD_ISSET(socka, &rfd)) // socka可读 { nRecLen = sizeof(cli); int nRecEcho = recvfrom(socka, recv_buf, sizeof(recv_buf), 0, (sockaddr*)&cli, &nRecLen); if (nRecEcho == INVALID_SOCKET) { printf("recvfrom()/n"); break; } printf("data to port 11111: %s/n", recv_buf); } if (FD_ISSET(sockb, &rfd)) // sockb 可读 { nRecLen = sizeof(cli); int nRecEcho = recvfrom(sockb, recv_buf, sizeof(recv_buf), 0, (sockaddr*)&cli, &nRecLen); if (nRecEcho == INVALID_SOCKET) { printf("recvfrom()/n"); break; } printf("data to port 22222: %s/n", recv_buf); } } } WSACleanup(); }

/************CLIENT*************/ #include #include #include #define SERVER_PORT_A 11111 // 服务器端口A #define SERVER_PORT_B 22222 // 服务器端口B typedef struct tagSERVER // 服务器 { char* ip; // ip地址 int nPort; // 端口号 } SERVER, *PSERVER; int SendData(SOCKET s, char *ip, int nPort, char *pData); // 发送数据到IP:nPort int main(int argc, char **argv) { int i; WSADATA wsaData; // socket数据 SOCKET sClient; // 客户端套接口 char send_buf[] = "hello! I am LiangFei whoes SNO=06060734"; // 发送的数据内容 int nSend; // 发送数据后的返回值 // 服务器 SERVER sers[] = { {"127.0.0.1", SERVER_PORT_A}, {"127.0.0.1", SERVER_PORT_B} }; int nSerCount = sizeof(sers) / sizeof(sers[0]); // 服务器个数 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) // 启动socket { printf("failed to start up socket!/n"); return 0; } // 建立客户端数据包套接口 sClient = socket(AF_INET, SOCK_DGRAM, 0); if (sClient == INVALID_SOCKET) { printf("socket()/n"); return 0; } for (i = 0; i < nSerCount; i++) { nSend = SendData(sClient, sers[i].ip, sers[i].nPort, send_buf); // 发送数据 if (nSend == 0) // 发送失败 { return 0; } else if (nSend == SOCKET_ERROR) // 套接口出错 { printf("sendto()/n"); return 0; } } closesocket(sClient); // 关闭套接口 WSACleanup(); // 卸载winsock return 0; } int SendData(SOCKET s, char *ip, int nPort, char *pData) { sockaddr_in ser; // 服务器端地址 ser.sin_family = AF_INET; // IP协议 ser.sin_port = htons(nPort); // 端口号 ser.sin_addr.s_addr = inet_addr(ip); // IP地址 int nLen = sizeof(ser); // 服务器地址长度 return sendto(s, pData, strlen(pData) + 1, 0, (sockaddr*)&ser, nLen); // 向服务器发送数据

你可能感兴趣的:(网络)