首页 > 学院 > 开发设计 > 正文

UDP的select用法

2019-11-06 06:32:01
字体:
来源:转载
供稿:网友
/************SERVER**************/#include <winsock2.h>#include <stdio.h>#define PORT_A	11111#define PORT_B  22222void 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放入要<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(); // 卸载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);	// 向服务器发送数据 
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表