理论
UDP(用户数据报协议)是一个无连接,不可靠的数据传输,其特点是简单,快捷。相比与TCP,UDP不需要建立连接(不需connect、accept函数),数据发送接收之后,不需要终止连接。基于UDP的程序,避免了TCP运行的开销,在效率与速度上具有更好的表现。UDP是无连接的,可能会有数据的丢失,延迟,这些需要应用程序自己处理。
编码
重要函数:
int recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen );
第一个参数: socket为对方的socket。
第二个参数: 接收数据的缓冲区。
第三个参数: 数据缓冲区大小。
第四个参数: 紧急状态,一般这为0。
第五个参数: 可选,对应AF_INET,返回对方IP,端口等socket地址标识sockaddr_in。
第六个参数: 可选,对应AF_INET,使用sockaddr_in结构大小。
该函数用于UDP接收数据。
返回值:如果未发生错误,则 recvfrom 将返回收到的字节数。如果连接已正常关闭,则返回值为零。否则,将返回值 SOCKET_ERROR,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。
int sendto(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen);
第一个参数: socket为对方的socket。
第二个参数: 发送数据的缓冲区。
第三个参数: 数据缓冲区大小。
第四个参数: 紧急状态,一般这为0。
第五个参数: 可选,对应AF_INET,对方IP,端口等socket地址标识sockaddr_in。
第六个参数: 可选,对应AF_INET,使用sockaddr_in结构大小。
该函数用于UDP发送数据。
#include <stdio.h>
#include <WinSock2.h>
#include <time.h>
#pragma comment (lib, "ws2_32.lib")
#pragma warning(disable:4996)
int main()
{
WSADATA wsa;
WSAStartup(WINSOCK_VERSION, &wsa);
SOCKET serversoc;
SOCKET clientsoc;
SOCKADDR_IN serveraddr;
SOCKADDR_IN clientaddr;
int client_len = sizeof(clientaddr);
int server_len = sizeof(serveraddr);
char* Send_data;
int Send_len;
char Recv_buf[64];
int result;
time_t nowtime;
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(9000);
serveraddr.sin_addr.s_addr = INADDR_ANY;
serversoc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
result = bind(serversoc, (SOCKADDR*)&serveraddr, server_len);
if (result == SOCKET_ERROR)
{
printf("套接字绑定失败!\n");
closesocket(serversoc);
return -1;
}
printf("Server is running.....\n");
clientsoc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
while (1)
{
result = recvfrom(serversoc, Recv_buf, 64, 0, (SOCKADDR*)&clientaddr, &client_len);
if (result >= 0)
{
Recv_buf[result] = 0;
printf("接收数据为: %s \n", Recv_buf);
nowtime = time(0);
Send_data = ctime(&nowtime);
Send_len = strlen(Send_data);
result = sendto(clientsoc, Send_data, Send_len, 0, (SOCKADDR*)&clientaddr, sizeof(clientaddr));
printf("Server is running.....\n");
}
}
closesocket(serversoc);
WSACleanup();
return 0;
}
#include <stdio.h>
#include <WinSock2.h>
#pragma comment (lib, "ws2_32.lib")
#pragma warning(disable:4996)
int main()
{
WSADATA wsa;
SOCKET serversoc;
SOCKADDR_IN serveraddr;
SOCKADDR_IN peeraddr;
int peer_len = sizeof(peeraddr);
char Recv_buf[64];
char* Send_data = "Hello,server!";
int Send_len = strlen(Send_data);
int time_out = 2000;
int result;
WSAStartup(WINSOCK_VERSION, &wsa);
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(9000);
serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (serveraddr.sin_addr.s_addr == INADDR_NONE)
{
printf("不可用地址!\n");
return -1;
}
serversoc = socket(AF_INET, SOCK_DGRAM, 0);
result = setsockopt(serversoc, SOL_SOCKET, SO_RCVTIMEO, (char*)&time_out, sizeof(time_out));
for (int i = 0; i < 3; i++)
{
result = sendto(serversoc, Send_data, Send_len, 0, (SOCKADDR*)&serveraddr, sizeof(serveraddr));
result = recvfrom(serversoc, Recv_buf, 64, 0, (SOCKADDR*)&peeraddr, &peer_len);
if (result >= 0)
{
Recv_buf[result] = 0;
printf("接收数据为: %s \n", Recv_buf);
}
}
closesocket(serversoc);
WSACleanup();
getchar();
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)