一个简单的UDP编程示例(有注释)

服务器端的代码如下。
  1 #include <stdio.h>
  2 #include <arpa/inet.h>
  3 #include <sys/types.h>
  4 #include <sys/socket.h>
  5 #include <netinet/in.h>
  6 #include <string.h>
  7 
  8 #define N 128
  9 #define errlog(errmsg) do{perror(errmsg);\
 10                           printf("---%s---%s---%d---\n",\
 11                                   __FILE__, __func__, __LINE__);\
 12                           return -1;\
 13                          }while(0)
 14 int main(int argc, const char *argv[])
 15 {
 16     int sockfd;
 17 
 18     struct sockaddr_in serveraddr, clientaddr;
 19     socklen_t addrlen = sizeof(serveraddr);
 20     char buf[N] = "";
 21 
 22     if(argc < 3){
 23         fprintf(stderr, "Usage: %s ip port\n", argv[0]);
 24         return -1;
 25     }
 26 
 27     /*创建套接字*/
 28     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
 29         errlog("socket error");
 30     }
 31 
 32     /*填充网络信息结构体
 33      *inet_addr:将点分十进制IP地址转换为网络字节序的整型数据
 34      *htons:将主机字节序转换为网络字节序
 35      *atoi:将数字型字符串转换为整型数据 
 36      */
 37     serveraddr.sin_family = AF_INET;
 38     serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
 39     serveraddr.sin_port = htons(atoi(argv[2]));
 40 
 41     /*将套接字与服务器网络信息结构体绑定*/
 42     if(bind(sockfd, (struct sockaddr *)&serveraddr, addrlen) < 0){
 43         errlog("bind error");
 44     }
 45 
 46     ssize_t bytes;
 47 
 48     while(1){
 49         if((bytes = recvfrom(sockfd, buf, N, 0,\
 50                        (struct sockaddr *)&clientaddr, &addrlen)) < 0){                                                                                                                                                                                                                                                                                                                                                                    
 51             errlog("recvfrom error");
 52         }
 53         else{
 54             printf("ip: %s, port: %d\n",
 55                     inet_ntoa(clientaddr.sin_addr),
 56                     ntohs(clientaddr.sin_port));
 57 
 58             if(strncmp(buf, "quit", 4) == 0){
 59                 printf("server quit\n");
 60                 break;
 61             }
 62             else{
 63                 printf("client: %s\n", buf);
 64 
 65                 strcat(buf, "-server");
 66 
 67                 if(sendto(sockfd, buf, N, 0,\
 68                             (struct sockaddr *)&clientaddr, addrlen) < 0){
 69                     errlog("sendto error");
 70                 }
 71             }
 72         }
 73     }
 74 
 75     close(sockfd);
 76     return 0;
 77 }
客户端的代码如下所示。
  1 #include <stdio.h>
  2 #include <arpa/inet.h>
  3 #include <sys/types.h>
  4 #include <sys/socket.h>
  5 #include <netinet/in.h>
  6 #include <string.h>
  7 
  8 #define N 128
  9 #define errlog(errmsg) do{perror(errmsg);\
 10                           printf("---%s---%s---%d---\n",\
 11                                   __FILE__, __func__, __LINE__);\
 12                           return -1;\
 13                          }while(0)
 14 int main(int argc, const char *argv[])
 15 {
 16     int sockfd;
 17     struct sockaddr_in serveraddr;
 18     socklen_t addrlen = sizeof(serveraddr);
 19     char buf[N] = "";
 20 
 21     if(argc < 3){
 22         fprintf(stderr, "Usage: %s ip port\n", argv[0]);
 23         return -1;
 24     }
 25 
 26     /*创建套接字*/
 27     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
 28         errlog("socket error");
 29     }
 30 
 31     /*填充网络信息结构体
 32      *inet_addr:将点分十进制IP地址转换为网络字节序的整型数据
 33      *htons:将主机字节序转换为网络字节序
 34      *atoi:将数字型字符串转换为整型数据 
 35      */
 36     serveraddr.sin_family = AF_INET;
 37     serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
 38     serveraddr.sin_port = htons(atoi(argv[2]));
 39 
 40 #if 0
 41     struct sockaddr_in clientaddr;
 42     clientaddr.sin_family = AF_INET;
 43     clientaddr.sin_addr.s_addr = inet_addr(argv[3]);
 44     clientaddr.sin_port = htons(atoi(argv[4]));
 45 
 46     if(bind(sockfd, (struct sockaddr *)&clientaddr, addrlen) < 0){
 47         errlog("bind error");
 48     }
 49 #endif
 50 
 51     while(1){
 52         fgets(buf, N, stdin);
 53         buf[strlen(buf) - 1] = '\0';
 54 
 55         if(sendto(sockfd, buf, N, 0,\
 56                     (struct sockaddr *)&serveraddr, addrlen) < 0){
 57             errlog("sendto error");
 58         }
 59 
 60         if(strncmp(buf, "quit", 4) == 0){
 61             printf("client quit\n");
 62             break;
 63         }
 64         else{
 65             if(recvfrom(sockfd, buf, N, 0,\
 66                         (struct sockaddr *)&serveraddr, &addrlen) < 0){
 67                 errlog("recv error");
 68             }
 69 
 70             printf("server: %s\n", buf);
 71         }
 72     }
 73     return 0;
 74 }     
运行结果如下所示。先运行服务器端,再运行客户端。客户端输入字符并发送,服务器端接收到之后,进行修改(合并字符串),再发送给客户端。当客户端输入“quit”之后,进程退出。
服务器端运行如下所示。
linux@Master:~/1000phone/net/udp$ ./server 192.168.44.134 7777
ip: 192.168.44.134, port: 36224
client: hello world
ip: 192.168.44.134, port: 36224
server quit
客户端运行如下所示。
linux@Master:~/1000phone/net/udp$ ./client 192.168.44.134 7777
hello world
server: hello world-server
quit
client quit

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值