《UDP用到的大多数函数在上一片TCP中已讲解,这儿就不再重复了,只有接受和发送所用的函数不同》
函数
(1)接受——recvfrom()
(2)发送——sendto()
a. 参数
sockfd: 表示一个已经建立的socket编号(描述符);
buf: 接受数据的缓冲区;
len: 缓冲区的大小;
flags: 调用操作方式,当设为0时,表示用阻塞方式接收;
src_addr: 发送方网络地址信息,指向装有发送方地址的缓存区;
addrlen: 指向src_addr缓存区长度值;
b. 返回值
成功返回读入/发送的字节数,失败返回-1。
2. 程序实现图
(1). 服务器的工作流程:首先调用socket函数创建一个Socket,然后调用bind函数将其与本机地址以及一个本地端口号绑定,接收到一个客户端时,服务器显示该客户端的IP地址,并将字串返回给客户端。
(2). 客户端的工作流程:首先调用socket函数创建一个Socket,填写服务器地址及端口号,从标准输入设备中取得字符串,将字符串传送给服务器端,并接收服务器端返回的字符串。最后关闭该socket。
3. 程序实现
//udp_server.c 1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<netinet/in.h> 5 #include<sys/types.h> 6 #include<sys/socket.h> 7 8 void usage(const char* argv) 9 { 10 printf("%s [ip] [port]\n",argv); 11 exit(0); 12 } 13 static int startup(int ip,int port) 14 { 15 //创建套接字 16 int sock=socket(AF_INET,SOCK_DGRAM,0); 17 if(sock<0) 18 { 19 perror("socket"); 20 exit(1); 21 } 22 //设置socket 23 struct sockaddr_in local; 24 local.sin_family=AF_INET; 25 local.sin_port=htons(port); 26 local.sin_addr.s_addr=inet_addr(ip); 27 //绑定 28 if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0) 29 { 30 perror("bind"); 31 exit(2); 32 } 33 return sock; 34 } 35 int main(int argc,char* argv[]) 36 { 37 if(argc!=3) 38 { 39 usage(argv[0]); 40 exit(3); 41 } 42 int r_ip=argv[1]; 43 int r_port=atoi(argv[2]); 44 45 int server_sock=startup(r_ip,r_port); 46 if(server_sock<0) 47 { 48 perror("startup"); 49 exit(4); 50 } 51 52 char buf[1024]; 53 struct sockaddr_in client; 54 socklen_t len =sizeof(client); 55 while(1) 56 { 57 memset(buf,'\0',sizeof(buf)); 58 ssize_t size = recvfrom(server_sock,buf,sizeof(buf)-1,0,\ (struct sock addr*)&client,&len); 59 if(size<0) 60 { 61 perror("recvform"); 62 exit(1); 63 } 64 printf("client [%s] [%d]# %s\n",inet_ntoa(client.sin_addr),\ ntohs(client.sin_port),buf); 65 } 66 return 0; 67 } //udp_client.c 1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<netinet/in.h> 5 #include<sys/types.h> 6 #include<sys/socket.h> 7 void usage(const char* argv) 8 { 9 printf("%s [ip] [port]\n",argv); 10 return ; 11 } 12 int main(int argc,char* argv[]) 13 { 14 if(argc!=3) 15 { 16 usage(argv[0]); 17 exit(1); 18 19 } 20 21 char* r_ip=argv[1]; 22 int r_port=atoi(argv[2]); 23 24 int sock=socket(AF_INET,SOCK_DGRAM,0); 25 if(sock<0) 26 { 27 perror("socket"); 28 exit(2); 29 } 30 31 struct sockaddr_in remote; 32 remote.sin_family=AF_INET; 33 remote.sin_port=htons(r_port); 34 remote.sin_addr.s_addr=inet_addr(r_ip); 35 36 char buf[1024]; 37 while(1) 38 { 39 memset(buf,'\0',sizeof(buf)); 40 printf("client: "); 41 fflush(stdout); 42 gets(buf); 43 ssize_t _s=sendto(sock,buf,sizeof(buf),0,\ (struct sockaddr*)&remote,sizeof(remote)); 44 if(_s<0) 45 { 46 perror("sendto"); 47 exit(3); 48 } 49 } 50 return 0; 51 } //start.sh 1 #!/bin/bash 2 3 ./udp_server 192.168.163.128 8080 //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
输出结果:
udp_server.c:
udp_client.c: