UDP服务器及客户端程序设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验二 UDP 服务器及客户端程序设计
一、实验目的
1、学习和掌握Linux 下的UDP 服务器基本原理和基本编程方法。
2、学习和掌握Linux 下的UDP 客户端基本原理和基本编程方法。
二、实验平台
ubuntu-8.04 操作系统
三、实验内容
1、编写Linux 下UDP 服务器套接字程序,服务器接收客户端发送的信息并显
示,同时显示客户的IP 地址、端口号,并向客户端发送信息。如果服务器接收的客户信息为“bye”,则退出循环,并关闭套接字。
2、编写Linux 下UDP 客户端套接字程序,结合实验三的UDP 服务器端程序,
实现以下功能:
(1)客户根据用户提供的IP 地址将用户从终端输入的信息发送给服务器,然后等待服务器的回应。
(2)服务器接收客户端发送的信息并显示,同时显示客户的IP 地址、端口号,并向客户端发送信息。如果服务器接收的客户信息为“bye”,则退出循环,并关闭套接字。
(3)客户接收、显示服务器发回的信息,并关闭套接字。
四、实验原理
1、使用UDP 套接字编程可以实现基于TCP/IP 协议的面向无连接的通信,它分为服务器端和客户端两部分,其主要实现过程如图3.1 所示。
2、UDP执行两种功能:
(1)向IP层添加另一个寻址(端口)层;
(2)检测传输中可能发生的数据损坏,并丢弃任何损坏的数据报。
3、UDP与TCP的区别:
(1)UDP套接字在使用之前不必进行连接;
(2)UDP套接字会保留消息边界,而TCP是一种字节流协议,不会保留它们;
(3)UDP提供的端到端服务是一种“尽力而为”的服务:不保证通过UDP套接字发送的消息将会到达其目的地。
4、UDP应答客户执行步骤:
(1)把应答字符串发送给服务器;
(2)接受应答;
(3)关闭程序。
5、UDP服务器:永远循环,接收一条消息,然后把相同的消息发送回它的任何发源地。
五、实验步骤
1、UDP服务器(udpserver.c)
(1)、登陆进入ubuntu 操作系统,新建一个文件,命名为udpserver.c(为了方便起见,可以进入“home”,再进入用户目录,在用户目录下新建udpserver.c)。(2)、在udpserver.c 中编写服务器端程序代码并保存。
(3)、在“终端”(“Applications”→“附件”→“终端”)中执行命令进入udpserver.c 所在目录。(pwd 命令可以显示当前所在目录;ls 命令可以显示当前目录下的
文件和文件夹信息;cd..命令可以进入上一级目录;cd 目录名命令可以进入
当前所示的某个目录。)
(4)、执行命令gcc –o udpserver udpserver.c 生成可执行文件udpserver。
(5)、执行命令./ udpserver,观察结果。
(6)、认真分析源代码,体会如何编写一个UDP 服务器端程序。
2、UDP客户端(udpclient.c)
(1)、登陆进入ubuntu 操作系统,新建一个文件,命名为udpclient.c(为了方便起见,可以进入“home”,再进入用户目录,在用户目录下新建udpclient.c)。(2)、在udpclient.c 中编写客户端程序代码并保存。将实验三完成的udpserver.c 拷贝到与udpclient.c 同一目录下。
(3)、在“终端”(“Applications”→“附件”→“终端”)中执行命令进入udpserver.c 和udpclient.c 所在目录。
(4)、执行命令gcc –o udpserver udpserver.c 生成可执行文件udpserver。
(5)、执行命令./ udpserver。
(6)、再开一个“终端”,进入udpserver.c 和udpclient.c 所在目录,执行命令gcc –o udpclient udpclient.c 生成可执行文件udpclient。
(7)、执行命令./ udpclient 127.0.0.1 hello。
(8)、观察两个“终端”出现的结果。
(9)、在客户端终端下执行命令./ udpclient 127.0.0.1 bye。
(10)、观察两个“终端”出现的结果。
(11)、认真分析源代码,体会如何编写一个UDP 客户端程序。
六、实验代码及分析
Udpserver.c
#include
#include
#include
#include
#include
#include
#include
#define PORT 1234 #define MAXDATASIZE 100
main()
{
int sockfd;//标识套接口的描述字
struct sockaddr_in server;//服务器
struct sockaddr_in client;//客户端
socklen_t addrlen;//地址长度
int num;//作为成功接收数据长度与否的标志
char buf[MAXDATASIZE];//数据缓冲区
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)//
IPv4协议,
数据报套接口 { perror("Creating socket failed."); exit(1);
}
bzero(&server,sizeof(server)); //初始化地址结构
server.sin_family=AF_INET;//地址族 server.sin_port=htons(PORT);端口号
server.sin_addr.s_addr = htonl (INADDR_ANY);
32位IPv4地址
if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) == -1) { perror("Bind() error.");
exit(1);
}
addrlen=sizeof(client);//客户端地址长度
while (1)
{
num = recvfrom(sockfd,buf,MAXDATASIZE,0,(struct sockaddr *)&client,&addrlen); //sockfd 套接口,buf 接收数据的缓冲区,MAXDATASIZE 接收数据缓冲区的最大长度, (struct sockaddr *)&client 客户端首地址,&addrlen 客户端地址长度
if (num < 0)
{
perror("recvfrom() error\n");
exit(1); 头文件
定义端口号和最大数据单元
创建套接字
套接字的设置 绑定套接字 数据接收并处理