一个简单的 UDP网络程序

 UDP网络程序采用的通信模型与TCP网络程序模型有很大的不同
UDP服务器首先进行初始化操作:调用函数socket创建一个数据报类型的套接字,函数bind将这个套接字与服务器的公认地址绑定在一起。然后调用函数recvfrom接收UDP客户机的数据报。UDP客户机首先调用函数socket创建一个数据报套接字,然后调用函数sendto向服务器发送数据报。在结束通信后,客户机调用close关闭UDP套接字,服务器继续使用这个UDP套接字接收其它客户机的数据报。
下面我们就学习一下图7-4中的一些函数用法。Socket函数的用法在上节已经介绍了,这里就不在叙述。
数据发送函数sendto的原型为:
#include
#include

int sendto(int sockfd,const void *msg,int len,unsigned int flags,const struct sockaddr *to,int tolen);
该函数比send()函数多了两个参数:to表示目的机的IP地址和端口号;tolen为地址长度。Sendto函数也返回实际发送的数据字节长度,出现错误时返回-1。

数据接收函数recvfrom的原型为:
#include
#include

int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);
参数from保存源机的IP地址和端口号;fromlen为此地址的长度。当recvfrom()返回时,fromlen包含实际存入from中的数据字节数,出现错误时返回-1。

下面我们就具体编写一个简单的基于UDP协议的服务器/客户端程序
服务器端程序server.c
/*************本程序用于创建服务端程序*****************/
#include  
#include  
#include  
#include  
#include  
#define MYPORT 8866 /*定义端口为8866*/
#define MAX_MSG_SIZE 1024

int main(void)
{
int sockfd,n,addrlen;
struct sockaddr_in server_addr;  /*服务器地址信息*/
struct sockaddr_in client_addr;   /*客户端地址信息*/
char buffer[MAX_MSG_SIZE];

sockfd=socket(AF_INET,SOCK_DGRAM,0); /*创建数据报套接字*/
if(sockfd
{
printf("Socket Error:%s/n",strerror(errno));
exit(1);
}
/* 服务器端填充 sockaddr_in结构 */
bzero(&server_addr,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(MYPORT);
/*绑定套接字*/
if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr))
{
    printf("Bind Error:%s/n",strerror(errno));
exit(1);
}
addrlen=sizeof(struct sockaddr);

printf(“The server is waiting datas:/n”);
  /* 接收客户端数据报,返回的为接收到的字节数 */
n=recvfrom(sockfd,buffer,MAX_MSG_SIZE,0,
(struct sockaddr *)&client_addr,&addrlen);
buffer[n]='/0';
printf("Got packer form %s/npacket contains:%s/n",
inet_ntoa(client_addr.sin_addr),buffer);
close(sockfd);
}

客户端程序client.c
#include  
#include  
#include  
#include  
#include  
#include  
#include
#include
#define MAX_BUF_SIZE 1024
#define MYPORT 8866  /*定义端口为8866*/

int main(int argc,char *argv[])
{
int sockfd,n;
struct sockaddr_in server_addr;
struct hostent *host;
char buffer[MAX_BUF_SIZE];

if(argc!=2)
{
printf("Usage:%s server_ip server_port/n",argv[0]);
exit(1);
}

/*gethostbyname可通过名称得到主机的IP地址*/
host=gethostbyname(argv[1]);

/*创建套接字*/
sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(sockfd
{
printf("Socket Error:%s/n",strerror(errno));
exit(1);
}

/* 填充服务端的资料 */
bzero(&server_addr,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(MYPORT);
server_addr.sin_addr=*((struct in_addr *)host->h_addr);

printf("Please input some characters:/n");
scanf("%s",buffer);

/*向服务器端发送数据报*/
n=sendto(sockfd,buffer,strlen(buffer),0,
(struct sockaddr *)&server_addr,sizeof(struct sockaddr));
printf("sent %d bytes to %s/n",n,inet_ntoa(server_addr.sin_addr));

close(sockfd);
return 0;
}

Makefile文件的编写
all:server client
server:server.c
gcc –o server server.c
client:client.c
gcc –o client client.c
clean:
rm –f server
rm –f client

编译运行:
运行make后会产生两个程序server(服务器端)和client(客户端)。先运行./server,这时屏幕显示“The server is waiting datas:”,然后进入等待状态。屏幕显示如下:
./server
The server is waiting datas:

然后在本机打开另外一个终端,运行./client localhost,表明此客户端是相位于本机的服务器发送数据报,这时屏幕显示如下:
./client localhost
Please input some characters:
Abcdefghijk
sent 11 bytes to 127.0.0.1

这时,运行服务器程序的终端会显示:
Got packer form 127.0.0.1 packet contains: Abcdefghijk

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值