在linux下基于udp的简单聊天窗口

在做聊天窗口前,我们需要先弄清几个问题

1.什么是udp?他有什么作用?他跟tcp有什么区别呢?

udp是用户数据报协议,他是面向数据报的,无连接,不可靠

tcp是传输控制协议,他是面向字节流的,面向连接,保证了可靠性

2.既然是聊天窗口,那么我们就需要一个客户端(udp_client),一个服务器(udp_server)

那么如何创建客户端与服务器端口呢,下面我们上代码

vim udp_client.c

  1 #include<stdio.h>                                                                                                                                        
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include<sys/socket.h>
  5 #include<sys/types.h>
  6 #include<arpa/inet.h>
  7 #include<netinet/in.h>
  8 int main(int argc,char*argv[])//接收三个参数: ./udp_client+ip地址+端口号
  9 {
 10     if(argc!=3)
 11     {
 12         printf("Usage:%s [ip][port]\n",argv[0]);
 13         return 1;
 14     }
 15     int sock=socket(AF_INET,SOCK_DGRAM,0);//创建套接字
 16     if(sock<0)
 17     {
 18         printf("socket error!");
 19         return 2;
 20     }
 21     char buf[128];
 22     struct sockaddr_in server;
 23     server.sin_family=AF_INET;
 24     server.sin_port=htons(atoi(argv[2]));//atoi将字符串转整形
 25     server.sin_addr.s_addr=inet_addr(argv[1]);
 26     socklen_t len=sizeof(server);
 27     for(;;)
 28     {
 29         buf[0]=0;
 30         ssize_t s=read(0,buf,sizeof(buf)-1); //0代表标准输入,1代表标准输出,2代表标准错误
 31         if(s>0)
 32         {
 33             buf[s-1]=0;//防止读入回车键
 34             sendto(sock,buf,strlen(buf),0,(struct sockaddr*)&server,len);
 35             s=recvfrom(sock,buf,sizeof(buf)-1,0,NULL,NULL);
 36             if(s>0)
 37             {
 38                 buf[s]=0;
 39                 printf("server echo# %s\n",buf);
 40             }
 41         }
 42     }
 43 close(sock);
 44 return 0;
 45 }

vim udp_server.c

  #include<stdio.h>                                                                                                                                        
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include<arpa/inet.h>
  5 #include<netinet/in.h>
  6 #include<sys/types.h>
  7 #include<sys/socket.h>
  8 #define SIZE 128
  9 void service(int sock)
 10 {
 11     char buf[SIZE];
 12     for(;;)
 13     {
 14         buf[0]=0;
 15         struct sockaddr_in peer;
 16         socklen_t len=sizeof(peer);
 17         ssize_t s=recvfrom(sock,buf,sizeof(buf)-1,0,(struct sockaddr*)&peer,&len);//buf为缓冲区,sockaddr*确定数据发送方地址
 18         {
 19             if(s>0)
 20             {
 21                 buf[s]=0;
 22                 printf("[%s : %d]#%s\n",inet_ntoa(peer.sin_addr),ntohs(peer.sin_port),buf);
 23                 sendto(sock,buf,strlen(buf),0,(struct sockaddr*)&peer,len);
 24             }
 25         }
 26     }
 27 }
 28 int main(int argc,char*argv[])
 29 {
 30     if(argc!=3)
 31     {
 32         printf("Usage:%s [ip] [port]\n",argv[0]);
 33         return 3;
 34     }
 35     int sock=socket(AF_INET,SOCK_DGRAM,0);
 36     if(sock<0)
 37     {
 38         printf("socket error!");
 39         return 1;
 40     }
 41     struct sockaddr_in local;
 42     local.sin_family=AF_INET;
 43     local.sin_port=htons(atoi (argv[2]));
 44     local.sin_addr.s_addr=inet_addr(argv[1]);
 45     if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)//对套接字进行地址和端口的绑定,local指向了一个结构体为sockaddr参数的指针
 46     {
 47         printf("bind error");
 48         return 2;
 49     }
 50     service(sock);
 51     close(sock);//关闭套接字
 52 }      

vim Makefile进行编译

 1 .PHONY:all
  2 all:udp_client udp_server
  3 udp_client:udp_client.c
  4     gcc -o $@ $^
  5 udp_server:udp_server.c
  6     gcc -o $@ $^
  7 .PHONY:clean
  8     clean:
  9     rm -f udp_client udp_server     

完成服务器和客户端的创建后,我们就可以通过访问同一个ip地址,进行通讯。用于测试的话我建议大家使用本地环回地址。

猜你喜欢

转载自blog.csdn.net/enjoymyselflzz/article/details/80554591