diediexiaomi 2020-04-10
linux
编写UDP服务器和客户端程序,客户端发送消息,服务器接收消息,并打印客户端的IP地址和端口号。
UDP是无需连接的通信,其主要实现过程如下:
同样,我们可以按照上一篇博客:基于TCP的客户端和服务器端的代码设计 的办法,将服务器代码分成两部分,一个是初始化,一个是收发数据。但是UDP服务器初始化较为简单,也可以直接写在main函数里。
UDP和TCP在读写数据上较为不同的是,sendto()和recvfrom(),这两个函数较为复杂。通过man手册查询得到:
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
参数1:文件描述符; 参数2:要发送的buf数据,是个指针
参数3:目的地的地址,是个指针,在使用时需要强制类型转换成(struct sockaddr *) 参数4:目的地的地址长度。具体的例子看下面代码
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
参数1:文件描述符; 参数2:要接收的buf缓冲区
参数3:接收的来源地址,在使用时需要强制类型转换成(struct sockaddr *) 参数4:一个指针,指向地址长度。具体的例子看下面代码
#include <stdio.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #define BUFFER_SIZE 100 #define PORT 1234 int32_t main(int32_t argc,char *argv[]) { struct sockaddr_in server; struct sockaddr_in client; char buf[BUFFER_SIZE]; int32_t len = sizeof(client); int32_t ret = 0; int32_t file_len = 0; if (argc != 2) { printf("Usage ./server [ip]\n"); return -1; } int32_t sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("create socket failed!"); exit(1); } bzero(&server, sizeof(struct sockaddr_in)); server.sin_family = AF_INET; server.sin_port = htons(PORT); /**< 主机字节序转化成网络字节序 */ server.sin_addr.s_addr = inet_addr(argv[1]); /**< 字符串转换in_addr的函数 */ /**< 绑定服务器 */ if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) { perror("bind failed!"); exit(1); } ret = recvfrom(sockfd, buf, BUFFER_SIZE, 0, (struct sockaddr *)&client, &len); if (ret < 0) { perror("recvfrom failed!"); exit(1); } buf[ret] = ‘\0‘; printf("client message: %s\n", buf); printf("client‘s ip is %s, port is %d.\n", inet_ntoa(client.sin_addr), htons(client.sin_port)); /**< 向客户端发送信息 */ if (sendto(sockfd, "Welcome to server", BUFFER_SIZE, 0, (struct sockaddr *)&client, len) < 0) { perror("send file len to client error"); } close(sockfd); return 0; }
#include <stdio.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #define BUFFER_SIZE 100 #define PORT 1234 int32_t main(int argc,char *argv[]) { struct sockaddr_in server; struct sockaddr_in peer; char buf[BUFFER_SIZE]; int32_t len = sizeof(peer); char sendbuf[BUFFER_SIZE] = "welcome to client"; int32_t num = 0; if (argc != 2) { printf("Usage ./client ip\n"); exit(1); } int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("create socket failed!"); exit(1); } bzero(&server, sizeof(struct sockaddr_in)); server.sin_family = AF_INET; server.sin_port = htons(PORT); server.sin_addr.s_addr = inet_addr(argv[1]); if (sendto(sockfd, sendbuf, BUFFER_SIZE, 0, (struct sockaddr *)&server, sizeof(server)) < 0) { perror("sendto socket failed!"); exit(1); } if ((num = recvfrom(sockfd, buf, BUFFER_SIZE, 0, (struct sockaddr *)&peer, &len)) < 0) { perror("recvfrom socket failed!"); exit(1); } buf[num] = ‘\0‘; printf("Server Message: %s\n", buf); close(sockfd); return 0; }
all:server client server:udpserver.c gcc udpserver.c -o server client:udpclient.c gcc udpclient.c -o client clean: rm -rf server client