Linux网络编程之UDP Socket程序示例
在网络传输协议中,TCP协议提供的是一种可靠的,复杂的,面向连接的数据流(SOCK_STREAM)传输服务,它通过三段式握手过程建立连接。TCP有一种“重传确认”机制,即接收端收到数据后要发出一个肯定确认的信号,发送端如果收到接收端肯定确认的信号,就会继续发送其他的数据,如果没有,它就会重新发送。
相对而言,UDP协议则是一种无连接的,不可靠的数据报(SOCK_DGRAM)传输服务。使用UDP套接口不用建立连接,服务端在调用socket()生成一个套接字并调用bind()绑定端口后就可以进行通信(recvfrom函数和sendto函数)了;客户端在用socket()生成一个套接字后就可以向服务端地址发送和接收数据了。
此处需要特别注意:TCP使用的是流套接字(SOCK_STREAM),UDP使用的是数据报套接字(SOCK_DGRAM)
UDP套接字编程范例:
server端代码如下:
/************************************************************************* >FileName:server.c >Author:SongLee ************************************************************************/ #include<sys/types.h> #include<sys/socket.h> #include<unistd.h> #include<netinet/in.h> #include<arpa/inet.h> #include<stdio.h> #include<stdlib.h> #include<errno.h> #include<netdb.h> #include<stdarg.h> #include<string.h> #defineSERVER_PORT8000 #defineBUFFER_SIZE1024 #defineFILE_NAME_MAX_SIZE512 intmain() { /*创建UDP套接口*/ structsockaddr_inserver_addr; bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=htonl(INADDR_ANY); server_addr.sin_port=htons(SERVER_PORT); /*创建socket*/ intserver_socket_fd=socket(AF_INET,SOCK_DGRAM,0); if(server_socket_fd==-1) { perror("CreateSocketFailed:"); exit(1); } /*绑定套接口*/ if(-1==(bind(server_socket_fd,(structsockaddr*)&server_addr,sizeof(server_addr)))) { perror("ServerBindFailed:"); exit(1); } /*数据传输*/ while(1) { /*定义一个地址,用于捕获客户端地址*/ structsockaddr_inclient_addr; socklen_tclient_addr_length=sizeof(client_addr); /*接收数据*/ charbuffer[BUFFER_SIZE]; bzero(buffer,BUFFER_SIZE); if(recvfrom(server_socket_fd,buffer,BUFFER_SIZE,0,(structsockaddr*)&client_addr,&client_addr_length)==-1) { perror("ReceiveDataFailed:"); exit(1); } /*从buffer中拷贝出file_name*/ charfile_name[FILE_NAME_MAX_SIZE+1]; bzero(file_name,FILE_NAME_MAX_SIZE+1); strncpy(file_name,buffer,strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer)); printf("%s\n",file_name); } close(server_socket_fd); return0; }
client端代码如下:
/************************************************************************* >FileName:client.c >Author:SongLee ************************************************************************/ #include<sys/types.h> #include<sys/socket.h> #include<unistd.h> #include<netinet/in.h> #include<arpa/inet.h> #include<stdio.h> #include<stdlib.h> #include<errno.h> #include<netdb.h> #include<stdarg.h> #include<string.h> #defineSERVER_PORT8000 #defineBUFFER_SIZE1024 #defineFILE_NAME_MAX_SIZE512 intmain() { /*服务端地址*/ structsockaddr_inserver_addr; bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=inet_addr("127.0.0.1"); server_addr.sin_port=htons(SERVER_PORT); /*创建socket*/ intclient_socket_fd=socket(AF_INET,SOCK_DGRAM,0); if(client_socket_fd<0) { perror("CreateSocketFailed:"); exit(1); } /*输入文件名到缓冲区*/ charfile_name[FILE_NAME_MAX_SIZE+1]; bzero(file_name,FILE_NAME_MAX_SIZE+1); printf("PleaseInputFileNameOnServer:\t"); scanf("%s",file_name); charbuffer[BUFFER_SIZE]; bzero(buffer,BUFFER_SIZE); strncpy(buffer,file_name,strlen(file_name)>BUFFER_SIZE?BUFFER_SIZE:strlen(file_name)); /*发送文件名*/ if(sendto(client_socket_fd,buffer,BUFFER_SIZE,0,(structsockaddr*)&server_addr,sizeof(server_addr))<0) { perror("SendFileNameFailed:"); exit(1); } close(client_socket_fd); return0; }
读者可以参考对比前一篇:Linux网络编程之socket文件传输示例,注意UDP和TCP工作流程的对比。以加深对该程序原理的理解。