UDP 协议通信服务器端客户端
UDP 协议进行通信
——服务器端 1、 UDP程序实例的基本使用情况和使用方法
输入命令 cmd2 调用C:\\Windows\\System32\\cmd2 udpc udps
显示结果
这个系统由服务器程序udps和客户及程序udpc两个程序组成,如果从客户机出入一个特定命令,并将这个命令发送到udps中去处理,其执行结果将在客户机的屏幕上显示出来。
1、在执行程序的时候,首先启动一个服务器程序。
端口号是该服务器程序所指定的一个接收包的端口号,客户机必须向该处发送包。在执行上述程序后则执行下面的客户机程序 2、“服务器的IP”也可以使用服务器的主机名或域名。 若两个程序在一台电脑上则服务器IP用127.0.0.1;若不在一台电脑上则服务器的IP用其所在电脑的IP(
要求
对教师党员的评价套管和固井爆破片与爆破装置仓库管理基本要求三甲医院都需要复审吗
两台电脑能Ping通)。客户端输入的端口号必须是服务器指定的端口。
1
3、 客户机方可以输入C:\\Windows\\System32\\下可执行的命令 如:help、arp、route print、quit等
从键盘上输入的字符原封不动的发送给服务器程序后,在服务器程序中则执行该字符串相对应的命令,并将执行结果发送给客户机程序。 2、 程序的执行实例和
流程
快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计
图
在这个实例中服务器的IP为白兰兰的IP(125.219.181.97) 在客户机端输入route print命令,则显示服务器的路由寻址
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
如下(不全)
2
服务器端的信息
如果输入help后没有任何反应,请确认udpc程序所指定的IP地址是否正确。若正确,再确认一下该IP地址的主机udps是否启动;再确认这些以后,如果执行udpc程序仍没有任何显示,那么请使用ping命令来检查通信是否能够进行,因为UDP协议属于无连接型通信,所以即使发生错误,也很难知道。
如果输入的命令一直是正确的,则只显示第一个命令,其余的都隐藏了。直到输入错误时,服务器端才有错误提示,如:
3、 处理流程
无论是服务器端还是和客户端,首先都要初始化套接口环境再创建一个套接口,利用bind()系统调用来绑定端口号和IP,只有这样才能使用UDP协议发送和接收一个包,但时至次计算机网络中还没有传输任何一个包。
对于客户机而言,如果从键盘上输入命令,在客户机上执行sendto()系统调用,向服务器发送包,那么在发送包之后,客户机则执行recvfrom()系统调用,等待从服务器返回的报文。
如果服务器收到从客户机发来的报文,则调用execute()和chulicom()函数。实质是调用C:\\Windows\\System32\\中的可执行程序。若存在该命令则给予客户机响应,若不存在输出 :您输入错误的命令。若命令不完整,服务器给出提示。
这些操作反复进行,如果在客户机上输入字符串quit,则程序运行结束。
3
在使用UDP协议时,即使客户机程序运行结束,也不讲这个事实传递给服务器。UDP协议进行的通信的基本模式,只是传递命令的请求包和应答包,并不传输其他包,因此通信方式简单。
客户机的处理 服务器的处理
开始 开始
设置端口号 创建一个套接口
socket()
创建一个套接口socket
()
Ip地址和端口绑定
Bind() Ip地址和端口绑定
Bind()
客户机循环,从键
盘上输入,当不是
EOF的时候反复进行 服务器循环接收报文
Recvfrom()
、
“quit”
所输入的字符包
串 对接收到的消息进行处理
Chulicom();execute()
其他
发送命令的执行结果
发送命令sendto() Sendto(); 接收报文recvfrom()
包
服务器循环 将接收到的报文在屏幕上输出
4
客户机循环
关闭该套接口
Closesocket()
关闭该套接口
Closesocket() 结束
结束
4、UDP服务器源程序及说明
#include
#include
#include
#include
#pragma comment (lib, "ws2_32.lib") #define BUFSIZE 65500
enum{CMD_NAME,DST_PORT};
int execute(char * command, char *buf,int bufmax);
void chulicom(char *buff ,char *send_buf);
void main(int argc,char *argv[]){
struct sockaddr_in server;
struct sockaddr_in client;
char recv_buf[BUFSIZE];
char send_buf[BUFSIZE];
5
int resize;
memset(recv_buf,0,sizeof(recv_buf));
memset(send_buf,0,sizeof(send_buf));
char if_;
SOCKET sk;
int serverport=12345;
if (argc==1) //如果双击打开程序
{
printf("是否使用默认端口:(y/n):"); AAA: if_ = getchar();
if (if_=='n')
{
printf("请输入服务器端端口:");
scanf("%d",&serverport);
}
else if (if_=='y') //默认端口
{
;
}
else{
fflush(stdin);
printf("输入错误:请重新输入。\n");
6
goto AAA;
}
}
WSADATA wsaData;
if( WSAStartup( MAKEWORD( 2, 2 ), &wsaData )!=0)
{
return ;
}
/*使用UDP协议打开一个套接字*/
if((sk=socket(AF_INET,SOCK_DGRAM,0))<0)
{
perror("socket");
exit(1);
}
/*设置服务器地址*/
memset((char *)&server, 0 ,sizeof(server));
server.sin_family=AF_INET;
server.sin_addr.s_addr=htonl (INADDR_ANY);// INADDR_ANY用
于对主机赋予允许连接全部IP地址的情况,若要限制所接收的IP地
址,不是将它指定为INADDR_ANY,而是指定一个特定的IP
server.sin_port=htons(serverport);
if(bind(sk,(struct sockaddr *)&server,sizeof(server))<0)
7
{
perror("bind");
exit(1);
}
printf("server已启动\n");
int len=sizeof(SOCKADDR); //利用recvfrom()系统来调用接收包,那么在报文存储到应用程序缓冲区的同时,也将客户机的IP地址和端口存储在sockaddr_in结构体中(client),在向客户机发送应答包时就是用这个值指定发送的地址
while((resize = recvfrom (sk,recv_buf , BUFSIZE-1, 0,(struct
sockaddr *)&client, &len))>=0){
printf("receive '%s'\n", recv_buf);
/*接收到的命令处理*/
memset(send_buf,0,sizeof(send_buf)); //在往发送缓冲去里面放消息时。先清空
chulicom(recv_buf,send_buf);//根据接收到的命令决定发送的内容
if (send_buf[0]=='\0') //当命令错误时,在可执行程序中检索不到不执行,发送缓冲区里面没内容
strcpy(send_buf,"你输入错误的命令~");
if(sendto(sk,send_buf,sizeof(send_buf)+1,0,(struct sockaddr
*)&client,sizeof(SOCKADDR))<0)
8
break;
printf("%s\n",send_buf);
}
closesocket(sk);
}
void chulicom(char *buff ,char *send_buf){
char cmd1[100],cmd2[50];
int cn;
strcpy(cmd2,buff);
strcpy(cmd1,"C:\\Windows\\System32\\");
strcat(cmd1,cmd2); //cmd1当前可执行程序的位置
execute(cmd2, send_buf,BUFSIZE); }
int execute(char *command, char *buf, int bufmax) // 执行命令,将执行结果存储在缓冲区中,先让可执行文件执行,将结果放在temp.txt里面然后再放入缓冲区发出去
{
FILE *fp;
int i;
freopen("temp.txt", "w", stdout); //把
标准
excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载
的输出流存放到temp.txt文件里面
system(command); //执行命令,输出来的信息被存放在temp.txt
9
中
if((fp=fopen("temp.txt","r"))==NULL) //命令错误,temp.txt里面没内容
{
perror(command); //输出错误原因
exit(EXIT_FAILURE);
}
i = 0;
char ch;
while ((ch=fgetc(fp))!=EOF&&i
10
#include
#include
#include
#include
#pragma comment (lib, "ws2_32.lib")
#define BUFSIZE 65500 #define DEFAULT_PORT 5320 enum {CMD_NAME,DST_IP,DST_PROT};
void main(int argc,char *argv[]){
struct sockaddr_in server; //服务器地址
struct sockaddr_in client; //客户机地址(自己的)
struct sockaddr_in tempS; //客户机地址(自己的)
struct hostent *he; //主机信息
char recv_buf[BUFSIZE]; //接受缓冲区
char send_buf[BUFSIZE]; //发送缓冲区
char servername[50];
char serverport[10];
char serverip[50];
SOCKET sk;
int port;
int tem;
int zero;
11
if (argc==1)
{
printf("请输入服务器端IP:");
scanf("%s",serverip);
printf("请输入服务器端端口:");
scanf("%s",serverport);
}
else{
strcpy(serverip,argv[1]);
strcpy(serverport,argv[2]);
}
//检索服务器端口号
sscanf(serverport,"%d",&port); //从一个字符串中读进与指定格式相符的数据.成功则返回参数数目,失败则返回0,错误原因存于errno中。
if ((tem=atoi(serverport))==0)
{
struct servent *se; //服务信息
if((se=getservbyname(serverport,"UDP"))!=NULL)
tem=(int)ntohs((u_short) se->s_port);
else
{
12
fprintf(stderr,"gethostbyname error");
exit (EXIT_FAILURE);
}
}
WSADATA wsaData;
if( WSAStartup( MAKEWORD( 2, 2 ), &wsaData )!=0)
{
return ;
}
if ((sk=socket (AF_INET,SOCK_DGRAM,0))<0)
{
perror(" socket");
exit (EXIT_FAILURE);
}
//设定客户机地址
memset((char *) &client,0,sizeof(client));
client.sin_family=AF_INET;
client.sin_addr.s_addr=htonl (INADDR_ANY);
client.sin_port=htons(0);
if (bind(sk,(struct sockaddr*)&client,sizeof(client))<0)
{
perror("bind");
13
exit (EXIT_FAILURE);
}
//设定服务器地址
memset((char *) &server,0,sizeof(server));
server.sin_family=AF_INET;
server.sin_addr.s_addr=inet_addr (serverip);
server.sin_port=htons(port);
zero=sizeof(SOCKADDR);
printf("UDP>");
getchar();
fflush(stdout); //fflush(stdout),使stdout清空,就会立刻输出所
有在缓冲区的内容。
while(scanf("%65500[^\n]",send_buf)!=EOF)
{
memset(recv_buf,0,sizeof(recv_buf));
char cmd[50];
sscanf(send_buf,"%s",cmd);
if (strcmp(cmd,"quit")==0)
break;
if(sendto(sk,send_buf,strlen(send_buf)+1,0,(struct sockaddr
*)&server,sizeof(SOCKADDR))<0)
break;
14
//处理来自服务器的应答报文
if ((tem=recvfrom(sk,recv_buf,BUFSIZE-1,0,(struct sockaddr
*)&tempS,&zero))<0)
;
// send_buf[0]='\0';
printf("%s\n",recv_buf);
printf("UDP>");
fflush(stdout);
getchar();
}
closesocket(sk);
}
UDP 协议进行通信
——客户端 一、udp进行通信的原理
UDP通信:
UDP是面向无连接的服务,特点就是,用这种协议传输数据速度快。使用这种协议追求的是传输的即时性而不是传输的质量。在实际应用中比如,QQ聊天的语聊,视频,还有网络电话使用的就是UDP协议,还有就是迅雷等一些下载工具用的也是UDP协议。
本系统由服务器程序udps和客户及程序udpc两个程序组成,如果从客户机输入一个特定命令,并将这个命令发送到udps中去处理,
15
其执行结果将在客户机的屏幕上显示出来。
客户机源程序主要完成了下面的处理功能:将从键盘输入端字符发送到一台服务器中,将来自服务器的应答报文在屏幕上显示出来。 二、
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
思想及流程
Udp通信的一般模式:
针对本系统,实现流程如下:
客户机的处理 服务器的处理
开始 开始
设置端口号 创建一个套接口
socket()
创建一个套接口socket
()
Ip地址和端口绑定
Bind() Ip地址和端口绑定
Bind()
16
客户机循环,从键
盘上输入,当不是
EOF的时候反复进行 服务器循环接收报文
Recvfrom()
、
“quit”
所输入的字符包
串 对接收到的消息进行处理
Chulicom();execute()
其他
发送命令的执行结果
发送命令sendto() Sendto(); 接收报文recvfrom()
包
服务器循环 将接收到的报文在屏幕上输出
客户机循环
关闭该套接口
Closesocket()
关闭该套接口
Closesocket() 结束
结束
三、各函数功能介绍如下:
Atoi(): 将字符串转换成一个整数值
getservbyname():返回与给定服务名对应的包含名字和服务号信息的servent结构指针
WSAStarup():是Windows SocKNDs Asynchronous的启动命令、Windows下的网络编程接口软件Winsock1 或 Winsock2 里面的一个命令。
17
Memset():将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向S的指针。 recvfrom():用来接收远程主机经指定的socket传来的数据,并把数据传到由参数buf指向的内存空间。
Closesocket():关闭套接字
四、操作步骤,及系统所实现的具体功能介绍:
4、 若服务器和客户极端在同一台电脑上执行,则输入ip 为 127.0.0.1
对于服务器端口可以选择默认的,也可以任意指定(默认端口为12345)
5、 若服务器端和客户端未在同一台电脑上, 则输入服务器所在电脑上的ip
6、 启动服务器后,可在client端输入命令,查询服务器的相关信
18
息
此时在服务器端显示客户机端输入的命令
又如:
19
3、 还可以输入其他命令验证:
客户机方可以输入C:\\Windows\\System32\\下可执行的命令 如:ipconfig、route print、arp等
20
21
7、 但注意,如果输入的命令一直是正确的,则只显示第一个命令,其余的都隐藏了。直到输入错误时,服务器端才有错误提示,如:
8、 输入quit,则退出系统
五、心的体会:
本次试验,我掌握了基本的socket编程,了解了tcp编程和udp编程的流程和它们之间的区别。尤其学会了基于udp的通信。这次虽然我做的只是客户端,但是同时也学到了服务器端的编程,可谓收获颇多。当然,这期间我也遇到了很多问题,比如对程序中用到的函数
22
不太理解,以及编程的大致思路把握不准确,不过通过老师的PPT
课件,又在网上查了一些知识,最重要的是在同学的帮助下,这些问
题都得到了很好的解决。
六、附源代码
//////client端
#include
#include
#include
#include
#include
#pragma comment (lib, "ws2_32.lib")
#define BUFSIZE 65500 #define DEFAULT_PORT 5320 enum {CMD_NAME,DST_IP,DST_PROT}; void main(int argc,char *argv[]){
struct sockaddr_in server; //服务器地址
struct sockaddr_in client; //客户机地址(自己的)
struct sockaddr_in tempS; //客户机地址(自己的)
struct hostent *he; //主机信息
char recv_buf[BUFSIZE]; //接受缓冲区
char send_buf[BUFSIZE]; //发送缓冲区
char servername[50];
char serverport[10];
char serverip[50];
SOCKET sk;
int port;
int tem;
int zero;
if (argc==1)
{
printf("请输入服务器端IP:");
scanf("%s",serverip);
printf("请输入服务器端端口:");
scanf("%s",serverport);
}
else{
strcpy(serverip,argv[1]);
strcpy(serverport,argv[2]);
}
23
//检索服务器端口号
sscanf(serverport,"%d",&port);
if ((tem=atoi(serverport))==0)
{
struct servent *se; //服务信息
if((se=getservbyname(serverport,"UDP"))!=NULL)
tem=(int)ntohs((u_short) se->s_port);
else
{
fprintf(stderr,"gethostbyname error");
exit (EXIT_FAILURE);
}
}
WSADATA wsaData;
if( WSAStartup( MAKEWORD( 2, 2 ), &wsaData )!=0)
{
return ;
}
if ((sk=socket (AF_INET,SOCK_DGRAM,0))<0)
{
perror(" socket");
exit (EXIT_FAILURE);
}
//设定客户机地址
memset((char *) &client,0,sizeof(client));
client.sin_family=AF_INET;
client.sin_addr.s_addr=htonl (INADDR_ANY);
client.sin_port=htons(0);
if (bind(sk,(struct sockaddr*)&client,sizeof(client))<0)
{
perror("bind");
exit (EXIT_FAILURE);
}
//设定服务器地址
memset((char *) &server,0,sizeof(server));
server.sin_family=AF_INET;
server.sin_addr.s_addr=inet_addr (serverip);
server.sin_port=htons(port);
zero=sizeof(SOCKADDR);
printf("UDP>");
getchar();
fflush(stdout);
while(scanf("%65500[^\n]",send_buf)!=EOF)
{
24
memset(recv_buf,0,sizeof(recv_buf));
char cmd[50];
sscanf(send_buf,"%s",cmd);
if (strcmp(cmd,"quit")==0)
break;
if(sendto(sk,send_buf,strlen(send_buf)+1,0,(struct sockaddr
*)&server,sizeof(SOCKADDR))<0)
break;
处理来自服务器的应答报文 //
if ((tem=recvfrom(sk,recv_buf,BUFSIZE-1,0,(struct sockaddr
*)&tempS,&zero))<0)
;
// send_buf[0]='\0';
printf("%s\n",recv_buf);
printf("UDP>");
fflush(stdout);
getchar();
}
closesocket(sk);
}
//server端
#include
#include
#include
#include
#pragma comment (lib, "ws2_32.lib") #define BUFSIZE 65500
enum{CMD_NAME,DST_PORT};
int execute(char * command, char *buf,int bufmax);
void chulicom(char *buff ,char *send_buf); void main(int argc,char *argv[]){
struct sockaddr_in server;
struct sockaddr_in client;
char recv_buf[BUFSIZE];
char send_buf[BUFSIZE];
int resize;
memset(recv_buf,0,sizeof(recv_buf));
memset(send_buf,0,sizeof(send_buf));
char if_;
SOCKET sk;
int serverport=12345;
25
if (argc==1) //?
{
printf("是否使用默认端口:(y/n):");
AAA: if_ = getchar();
if (if_=='n')
{
printf("请输入服务器端端口:");
scanf("%d",&serverport);
}
else if (if_=='y')
{
;
}
else{
fflush(stdin);
printf("输入错误:请重新输入。\n");
goto AAA;
}
}
WSADATA wsaData;
if( WSAStartup( MAKEWORD( 2, 2 ), &wsaData )!=0)
{
return ;
}
/*使用UDP协议打开一个套接字*/
if((sk=socket(AF_INET,SOCK_DGRAM,0))<0)
{
perror("socket");
exit(1);
}
/*设置服务器地址*/
memset((char *)&server, 0 ,sizeof(server));
server.sin_family=AF_INET;
server.sin_addr.s_addr=htonl (INADDR_ANY);
server.sin_port=htons(serverport);
if(bind(sk,(struct sockaddr *)&server,sizeof(server))<0)
{
perror("bind");
exit(1);
}
printf("server已启动\n");
int len=sizeof(SOCKADDR);
while((resize = recvfrom (sk,recv_buf , BUFSIZE-1, 0,(struct sockaddr *)&client,
&len))>=0){
26
printf("receive '%s'\n", recv_buf);
/*接收到的命令处理*/
memset(send_buf,0,sizeof(send_buf));
chulicom(recv_buf,send_buf);
if (send_buf[0]=='\0')
strcpy(send_buf,"你输入错误的命令~");
if(sendto(sk,send_buf,sizeof(send_buf)+1,0,(struct sockaddr
*)&client,sizeof(SOCKADDR))<0)
break;
printf("%s\n",send_buf);
}
closesocket(sk);
}
void chulicom(char *buff ,char *send_buf){
char cmd1[100],cmd2[50];
int cn;
strcpy(cmd2,buff);
strcpy(cmd1,"C:\\Windows\\System32\\");
strcat(cmd1,cmd2);
execute(cmd2, send_buf,BUFSIZE); }
int execute(char *command, char *buf, int bufmax) // 执行命令,将执行结果存储在缓冲区中
{
FILE *fp;
int i;
freopen("temp.txt", "w", stdout);
system(command);
if((fp=fopen("temp.txt","r"))==NULL)
{
perror(command);
exit(EXIT_FAILURE);
}
i = 0;
char ch;
while ((ch=fgetc(fp))!=EOF&&i
本文档为【UDP 协议通信服务器端客户端】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。