UDP协议简介
用户数据包协议(UDP)实时提供了读取数据的直接访问权,并且传输时无连接、不执行端对端的可靠性检查,因此在传输可靠性高的数据信息时,一般采用TCP协议,而不是UDP协议。虽然UDP协议有不可靠的因素,但其有代码小、速度快和系统开销小等优点。
1、sendto ()函数
#include < sys/types.h >
#include < sys/socket.h >
int sendto ( int s , const void * msg, int len, unsigned int flags, const struct sockaddr * to , int tolen ) ;
sendto() 用来将数据由客户端传给服务器。参数s为已建好连线的套接字描述符,如果利用UDP协议则不需经过连接操作。参数msg是指向发送信息缓冲区的指针,参数flags 一般设0。参数to为存放接收处信息的指针,也就是存放服务器的IP地址及端口号,接收的信息将存放在sockaddr 结构体中,结构sockaddr请参考bind()。参数tolen为sockaddr的结构长度。
2、 recvfrom()函数
#include <sys/types.h>
#include <sys/socket.h>
nt recvfrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from,int *fromlen);
参数s为套接字描述符;buf参数指向客户端发送信息的指针;len表示缓冲区的最大长度;flags通常设置为0;from表示发送此信息处的地址指针,指向的结构体存放着客户端的IP地址和端口号;fromlen指向该结构体的大小。
1 #include <stdio.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <sys/types.h>
9 #include <sys/wait.h>
10 #include <sys/socket.h>
11 #include <strings.h>
12 #include <netinet/in.h>
13 #include <netinet/ip.h>
14 #include <signal.h>
15 #include <errno.h>
16 #include <arpa/inet.h>
17 #define SERV_PORT 5001
18 #define SERV_IP_ADDR "192.168.192.143"
19 #define QUIT_STR "quit"
20 int main()
21 {
22 int fd =-1;
23 struct sockaddr_in sin;
24
25 if( (fd = socket(AF_INET,SOCK_DGRAM,0)) < 0){
26 perror("socket");
27 exit(1);
28 }
29
30 int b_reuse = 1;
31 setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&b_reuse,sizeof(int));
32 bzero(&sin,sizeof(sin));
33 sin.sin_family = AF_INET;
34 sin.sin_port = htons(SERV_PORT);
35 #if 1
36 sin.sin_addr.s_addr = htonl(INADDR_ANY);
37 #else
38 if(inet_pton(AF_INET,SERV_IP_ADDR,&sin.sin_addr) != 1){
39 perror("inet_pton");
40 exit(1);
41 }
42 #endif
43
44 if(bind(fd,(struct sockaddr *)&sin,sizeof(sin)) < 0){
45 perror("bind error");
46 exit(1);
47 }
48 printf("UDP Server starting.....Okay\n");
49 char buf[BUFSIZ];
50 struct sockaddr_in cin;
51 socklen_t addrlen = sizeof(cin);
52 while(1)
53 {
54 bzero(buf,BUFSIZ);
55 if(recvfrom(fd,buf,BUFSIZ -1,0,(struct sockaddr *)&cin,&addrlen) < 0){
56
57 perror("recvfrom");
58 exit(1);
59 }
60
61 char ipv4_addr[16];
62 if(! inet_ntop(AF_INET,(void *)&cin.sin_addr,ipv4_addr,sizeof(cin))){
63 perror("inet_ntop");
64 exit(1);
65 }
66
67 printf("Recived from(%s:%data:%s\n",ipv4_addr,ntohs(cin.sin_port),buf);
68 if(!strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))){
69 printf("Client(%s: %d) is exiting!\n",ipv4_addr,ntohs(cin.sin_port));
70 break;
71 }
72
73 }
74 return 0;
75 }
~
1
2 #include <stdio.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <strings.h>
9 #include <netinet/in.h>
10 #include <netinet/ip.h>
11 #include <errno.h>
12 #include <arpa/inet.h>
13 #define SERV_PORT 5001
14 #define SERV_IP_ADDR "192.168.192.143"
15 #define BACKLOG 5
16 #define QUIT_STR "quit"
17
18 void usage(char *s)
19 {
20 printf("\nThis is UDP demo!\n");
21 printf("\n%s serv_ip serv_port",s);
22 printf("\n\t serv_ip:server ip address");
23 printf("\n\t serv_port:server port(>5000)\n\n");
24 }
25
26 int main(int argc,char *argv[])
27 {
28 int fd = -1;
29 int port = -1;
30 if(argc != 3){
31 usage(argv[0]);
32 exit(1);
33
34 }
35 struct sockaddr_in sin;
36
37 if( (fd = socket(AF_INET,SOCK_DGRAM,0)) < 0){
38 perror("socket");
39 exit(1);
40 }
41 port = atoi(argv[2]);
42 if(port < 5000){
43 usage(argv[0]);
44 exit(1);
45 }
46
47
48 bzero(&sin,sizeof(sin));
49 sin.sin_family = AF_INET;
50 sin.sin_port = htons(port);
51 if(inet_pton(AF_INET,argv[1],(void*)&sin.sin_addr) != 1){
52 perror("inet_pton");
53 exit(1);
54 }
55
56 printf("UDP client starting....OK!\n");
57 char buf[BUFSIZ];
58 while(1){
59 fprintf(stderr,"Please input the string to server:");
60 bzero(buf,BUFSIZ);
61 if(fgets(buf,BUFSIZ-1,stdin) ==NULL){
62 continue;
63 }
64 sendto(fd,buf,strlen(buf),0,(struct sockaddr *)&sin,sizeof(sin));
65 if(!strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))){
66 printf("Client is exiting!\n");
67 break;
68
69 }
70 }
71 close(fd);
72 return 0;
73 }
~
book@100ask:~/socket$ ./udpclient 192.168.192.143 5001 客户端输入三个参数
UDP client starting....OK!
Please input the string to server:China
Please input the string to server:2021
Please input the string to server:456
book@100ask:~/socket$ ./udpserver 服务器端读取数据
UDP Server starting.....Okay
Recived from(192.168.192.143:55437) data:China
Recived from(192.168.192.143:55437) data:2021
Recived from(192.168.192.143:55437) data:456
|