基于UDP的select函数用法

基于UDP的select函数用法

基于UDP的select函数用法

最新推荐文章于 2023-09-22 10:36:03 发布

转载

最新推荐文章于 2023-09-22 10:36:03 发布

·

1.2w 阅读

·

3

·

23

文章标签:

#网络

#UDP

#编程

网络编程

专栏收录该内容

7 篇文章

订阅专栏

本文介绍了一个简单的双端口UDP服务器和客户端的实现方法。服务器通过两个不同的端口监听并接收来自客户端的数据,客户端则向这两个端口发送相同的数据。该示例展示了如何使用Winsock库创建和管理UDP套接字。

/************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); // 向服务器发送数据

相关推荐

安防工程包括哪些?安防工程指的是什么?
365bet官方平台开户

安防工程包括哪些?安防工程指的是什么?

📅 09-05 👁️ 3515
白痴的解释
bt365体育手机客户端

白痴的解释

📅 09-03 👁️ 8840
华为鼠标如何更换电池
365bet官方平台开户

华为鼠标如何更换电池

📅 07-20 👁️ 123
[记录]已经转区到碧海潮生
365bet网上网投

[记录]已经转区到碧海潮生

📅 07-08 👁️ 1877
解码爱沙尼亚:揭秘国际赛场上的北欧明星力量
365bet网上网投

解码爱沙尼亚:揭秘国际赛场上的北欧明星力量

📅 08-19 👁️ 1350