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工作流程的对比。以加深对该程序原理的理解。