五、用户数据报传输(UDP)

时间:2021-04-22 23:48:01

1、UDP常用的发送和接收函数

int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);
int sendto(int sockfd,const void *msg,int len,unsigned int flags,struct sockaddr *to,int tolen);

sockfd,buf,len的意义和read,write中的参数是一样的,分别表示套接字描述符,发送或接收的缓冲区及大小。

recvfrom负责从sockfd接收数据,如果from不是NULL,那么在from里面存储了信息来源的情况,如果对信息的来源不感兴趣,可以将from和fromlen设置为NULL。

sendto负责向to发送消息,此时在to里面存储了信息接收方的详细资料。

2、实例演示

服务端程序

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
#define SERVER_PORT 8888
#define MAX_MSG_SIZE 1024 void udps_respon(int sockfd)
{
struct sockaddr_in addr;
int n;
socklen_t addrlen;
char msg[MAX_MSG_SIZE]; while ()
{ /* 从网络上读,写到网络上面去 */
memset(msg, , sizeof(msg));
addrlen = sizeof(struct sockaddr);
n = recvfrom(sockfd, msg, MAX_MSG_SIZE, ,
(struct sockaddr*)&addr, &addrlen);
/* 显示服务端已经收到了信息 */
fprintf(stdout, "I have received %s", msg);
sendto(sockfd, msg, n, , (struct sockaddr*)&addr, addrlen);
}
} int main(void)
{
int sockfd;
struct sockaddr_in addr; sockfd = socket(AF_INET, SOCK_DGRAM, );
if (sockfd<)
{
fprintf(stderr, "Socket Error:%s\n", strerror(errno));
exit();
}
bzero(&addr, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(SERVER_PORT);
if (bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))<)
{
fprintf(stderr, "Bind Error:%s\n", strerror(errno));
exit();
}
udps_respon(sockfd);
close(sockfd);
}

客户端程序

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
#define MAX_BUF_SIZE 1024 void udpc_requ(int sockfd, const struct sockaddr_in *addr, socklen_t len)
{
char buffer[MAX_BUF_SIZE];
int n;
while (fgets(buffer, MAX_BUF_SIZE, stdin))
{ /* 从键盘读入,写到服务端 */
sendto(sockfd, buffer, strlen(buffer), , addr, len);
bzero(buffer, MAX_BUF_SIZE); /* 从网络上读,写到屏幕上 */
memset(buffer, , sizeof(buffer));
n = recvfrom(sockfd, buffer, MAX_BUF_SIZE, , NULL, NULL);
if (n <= )
{
fprintf(stderr, "Recv Error %s\n", strerror(errno));
return;
}
buffer[n] = ;
fprintf(stderr, "get %s", buffer);
}
} int main(int argc, char **argv)
{
int sockfd, port;
struct sockaddr_in addr; if (argc != )
{
fprintf(stderr, "Usage:%s server_ip server_port\n", argv[]);
exit();
} if ((port = atoi(argv[]))<)
{
fprintf(stderr, "Usage:%s server_ip server_port\n", argv[]);
exit();
} sockfd = socket(AF_INET, SOCK_DGRAM, );
if (sockfd<)
{
fprintf(stderr, "Socket Error:%s\n", strerror(errno));
exit();
}
/* 填充服务端的资料 */
bzero(&addr, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
if (inet_aton(argv[], &addr.sin_addr)<)
{
fprintf(stderr, "Ip error:%s\n", strerror(errno));
exit();
}
if (connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) == -)
{
fprintf(stderr, "connect error %s\n", strerror(errno));
exit();
}
udpc_requ(sockfd, &addr, sizeof(struct sockaddr_in));
close(sockfd);
}