基于 C 语言的 UDP 网络基本编程

2015-01-13 12:11:35   最后更新: 2015-01-13 12:11:35   访问数量:1224




UDP 是无连接、不可靠的数据报协议,而 TCP 是面向连接的可靠字节流协议,他们具有非常大的差异

DNS、NFS 和 DNMS 等领域,UDP 要比 TCP 更为适用

下图展示了 UDP 连接的生命周期

 

客户不与服务器建立连接,而是通过指定目的地地址为参数调用 sendto 函数发送数据报,另一端通过 recvfrom 函数接收数据报

这两个函数与标准的 read 和 write 函数非常像

函数原型

ssize_t recvfrom(int sockfd, void *buf, int len, int flags, struct sockaddr *from, socket_t *addrlen); ssize_t sendto(int sockfd, const void *buf, int len, int flags, const struct sockaddr *to , socket_t addrlen);

 

调用成功返回读写数据长度,否则返回 -1

参数说明

前三个参数与标准的 read 或 write 函数完全一致,无需再次说明

sendto 的 to 参数是一个包含接收者地址的套接字地址结构,由 addrlen 参数指定该结构的大小

而 recvfrom 函数的最后两个参数则用于返回,将数据报发送者地址保存在 from 参数中,addrlen 参数则保存 from 地址结构的大小

server

/** * author: 龙泉居士 * date: 2012-08-02 */ #include <stdio.h> #include <string.h> #include <ctype.h> #include <netinet/in.h> #include <arpa/inet.h> #define MAX_LINE 80 #define SERV_PORT 8000 int main () { struct sockaddr_in servaddr, cliaddr; socklen_t cliaddr_len; int sockfd; char buf[MAX_LINE]; char str[INET_ADDRSTRLEN]; int i, n; sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { perror ("Creating socket failed"); return -1; } bzero (&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); if (bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) { perror ("Bind failed"); return -1; } printf ("Accepting connections ... \n"); while (1) { cliaddr_len = sizeof(cliaddr); n = recvfrom (sockfd, buf, MAX_LINE, 0, (struct sockaddr *)&cliaddr, &cliaddr_len); if (n == -1) { perror ("Receive error"); return -1; } printf ("received from %s at port %d\n",\ inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),\ ntohs(cliaddr.sin_port)); for (i=0; i<n; ++i) buf[i] = toupper(buf[i]); n = sendto(sockfd, buf, n, 0, (struct sockaddr*)&cliaddr, sizeof(cliaddr)); if (n == -1) { perror ("Send error"); return -1; } } return 0; }

 

client

/** * author: 龙泉居士 * date: 2012-08-02 * file: main.c */ #include <stdio.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> #define MAX_LINE 80 #define SERV_PORT 8000 int main () { struct sockaddr_in servaddr; int sockfd, n; char buf[MAX_LINE]; sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { perror ("Creating socket failed"); return -1; } bzero (&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; inet_pton (AF_INET, "127.0.0.1", &servaddr.sin_addr); servaddr.sin_port = htons(SERV_PORT); while (fgets(buf, MAX_LINE, stdin) != NULL) { n = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&servaddr, sizeof(servaddr)); if (n == -1) { perror ("Send error"); return -1; } n = recvfrom (sockfd, buf, MAX_LINE, 0, NULL, 0); if (n == -1) { perror ("Receive error"); return -1; } int wn = write (STDOUT_FILENO, buf, n); if (wn != n) { printf ("Write error"); return -1; } } return 0; }

 

 






读书笔记      技术帖      linux      unix      c语言      unp      unix网络编程      udp      socket      龙潭书斋      sendto      recvfrom      数据报     


京ICP备15018585号