在做聊天窗口前,我们需要先弄清几个问题
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地址,进行通讯。用于测试的话我建议大家使用本地环回地址。