Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1854106
  • 博文数量: 383
  • 博客积分: 10011
  • 博客等级: 上将
  • 技术积分: 4061
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-24 18:53
文章分类

全部博文(383)

文章存档

2011年(1)

2010年(9)

2009年(276)

2008年(97)

我的朋友

分类: LINUX

2008-11-30 14:24:52

UDP网络程序采用的通信模型与TCP网络程序模型有很大的不同,具体见图7-4所示。

 

UDP服务器首先进行初始化操作:调用函数socket创建一个数据报类型的套接字,函数bind将这个套接字与服务器的公认地址绑定在一起。然后调用函数recvfrom接收UDP客户机的数据报。UDP客户机首先调用函数socket创建一个数据报套接字,然后调用函数sendto向服务器发送数据报。在结束通信后,客户机调用close关闭UDP套接字,服务器继续使用这个UDP套接字接收其它客户机的数据报。

下面我们就学习一下图7-4中的一些函数用法。Socket函数的用法在上节已经介绍了,这里就不在叙述。

数据发送函数sendto的原型为:

#include

#include < sys/socket.h >

 

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 < sys/socket.h >

 

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<0)

{

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))<0)

{

    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<0)

{

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

阅读(972) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~