UDP的select用法

来源:互联网 发布:oracle数据库阻塞 编辑:程序博客网 时间:2024/06/05 16:02
/************SERVER**************/#include <winsock2.h>#include <stdio.h>#define PORT_A11111#define PORT_B  22222void main(int argc, char **argv){WSADATA wsaData; // 套接口信息数据SOCKET socka;// 套接口aSOCKET sockb;// 套接口bint nPortA = PORT_A;int nPortB = PORT_B;fd_set rfd;// 读描述符集timeval timeout;// 定时变量sockaddr_in addr; // 告诉sock 应该在什么地方licencechar 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);// 创建数据报sockaif (socka == INVALID_SOCKET){printf("socket()/n");return;}sockb = socket(AF_INET, SOCK_DGRAM, 0);// 创建数据报sockbif (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;}// 设置超时时间为6stimeout.tv_sec = 6;timeout.tv_usec = 0;memset(recv_buf, 0, sizeof(recv_buf)); // 清空接收缓冲区while (true){FD_ZERO(&rfd); // 在使用之前总是要清空// 开始使用selectFD_SET(socka, &rfd); // 把socka放入要<a href="http://lib.csdn.net/base/softwaretest" class='replace_word' title="软件测试知识库" target='_blank' style='color:#df3434; font-weight:bold;'>测试</a>的描述符集中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 <winsock2.h>#include <stdio.h>#include <stdlib.h>#define SERVER_PORT_A 11111// 服务器端口A#define SERVER_PORT_B 22222// 服务器端口Btypedef struct tagSERVER// 服务器{char* ip;// ip地址int nPort;// 端口号} SERVER, *PSERVER;int SendData(SOCKET s, char *ip, int nPort, char *pData); // 发送数据到IP:nPortint 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(); // 卸载winsockreturn 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);// 向服务器发送数据 

0 0