udp接收函数Word格式文档下载.docx

上传人:b****6 文档编号:17267301 上传时间:2022-11-30 格式:DOCX 页数:5 大小:18.37KB
下载 相关 举报
udp接收函数Word格式文档下载.docx_第1页
第1页 / 共5页
udp接收函数Word格式文档下载.docx_第2页
第2页 / 共5页
udp接收函数Word格式文档下载.docx_第3页
第3页 / 共5页
udp接收函数Word格式文档下载.docx_第4页
第4页 / 共5页
udp接收函数Word格式文档下载.docx_第5页
第5页 / 共5页
亲,该文档总共5页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

udp接收函数Word格式文档下载.docx

《udp接收函数Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《udp接收函数Word格式文档下载.docx(5页珍藏版)》请在冰豆网上搜索。

udp接收函数Word格式文档下载.docx

  例程:

  socKeTsocksrv=socket(AF_IneT,socK_DgRAm,0);

  charrecvbuf[64];

  socKADDR_Inaddrclient;

  intlen=sizeof(socKADDR);

  bufsize=recvfrom(socksrv,recvbuf,sizeof(recvbuf),0,(socKADDR*)

  2.select函数解析

  intselect(int,fd_set*,fd_set*,fd_set*,conststructtimeval*);

fds:

本参数忽略,仅起到兼容作用。

  readfds:

(可选)指针,指向一组等待可读性检查的套接口。

  writefds:

(可选)指针,指向一组等待可写性检查的套接口。

  exceptfds:

(可选)指针,指向一组等待错误检查的套接口。

  timeout:

select()最多等待时间,对阻塞操作则为nuLL。

  timeout为结构timeval,用来设置select()的等待时间,其结构定义如下

  structtimeval{

  time_ttv_sec;

//second秒

  time_ttv_usec;

//microsecond微妙

  };

  本函数用于确定一个或多个套接口的状态。

对每一个套接口,调用者可查询它的可读性、可写性及错误状态信息。

用fd_set结构来表示一组等待检查的套接口。

  FD_cLR(s,*set):

从集合set中删除描述字s。

  FD_IsseT(s,*set):

若s为集合中一员,非零;

否则为零。

  FD_seT(s,*set):

向集合添加描述字s。

  FD_ZeRo(*set):

将set初始化为空集nuLL。

  timeout参数控制select()完成的时间。

若timeout参数为空指针,则select()将一直阻塞到有一个描述字满足条件。

否则的话,timeout指向一个timeval结构,其中指定了select()调用在返回前等待多长时间。

如果timeval为{0,0},则select()立即返回,这可用于探询所选套接口的状态。

如果处于这种状态,则select()调用可认为是非阻塞的。

  返回值:

  select()调用返回处于就绪状态并且已经包含在fd_set结构中的描述字总数;

如果超时则返

  回0;

否则的话,返回socKeT_eRRoR错误

  例程:

  fd_setreadfds;

  FD_ZeRo(//每次循环都要清空集合,否则不能检测描述符变化FD_seT(sockfd,//添加描述符

  structtimevaltv;

  tv.tv_sec=3;

//seconds时间的长短和对面数据发送的频率有关

  tv.tv_usec=50;

//microseconds

  select(sockfd+1,

  3.不用select方式设置非阻塞

  intimode=1;

//0:

阻塞1:

非阻塞

  ioctlsocket(sock,FIonbIo,(u_longFAR*)

  篇二:

uDp通信流程

  uDp发送过程:

1.应用层:

绑定uDp套接字我们必须先创建一个

  uDp套接字,通过调用udp_new()进行申请,然后调用udp_bind()绑定在uDp端口上,在这个调用过程中,我们必须编写一个用于处理这个uDp套接字接收到的数据报文的函数,并把这个函数作为

  udp_bind()的参数,以后当套接字接收到数据报文时会自动调用这个函数,我们将在后面介绍这个函数怎么调用的。

绑定结束之后,必须调用

  udp_connect()将数据报文的目的地址绑定在uDp的数据结构中,最后就是调用udp_send()把数据报文发送出去。

  udp_bind()的处理流程图

(:

udp接收函数)  2.传输层的处理

  做好应用层的处理之后,数据报文被提交到uDp层,udp_send()函数中首先给数据报文加入uDp头部,然后调用ip_route()选择一个合适的网络接口进行发送,最后调用ip_output()把数据报文传入Ip层。

  3.Ip层的处理

  ip_route()函数比较各个网络接口的Ip地址是否与目的Ip地址在同一子网中,如果有,就把它当成发送的网络接口返回,如果没有就返回一个默认的网络接口。

在ip_output()函数中,先给数据报文加上Ip头部,然后比较目的Ip地址与网络接口的Ip地址是否在同一网段,如果不是,就必须先把数据报文发送到网关,于是使用网关的Ip地址作为目的主机,如果目的Ip地址与网络接口的Ip地址在同一网段,则把目的Ip地址作为目的主机。

接着调用arp_lookup()在ARp缓存中查找目的主机的mAc地址,找到了调用ethernet_output()把数据报文传入到数据链路层发送,如果找不到,就调用arp_query()发送ARp请求解析目的主机的mAc地址。

  4.ARp协议的处理

  arp_lookup()实现在本地ARp缓存中查找目的主机的mAc地址,找到了返回该mAc地址,找不到返回nuLL。

  arp_query()函数中构造一个ARp请求报文,然后调用ethernet_output()把该报文送到数据链路层发送。

  5.数据链路层的处理

  数据链路层的处理就是给数据报文添上相对的以太网头部,然后调用lowlever_output()直接把报文传送出去。

  uDp接收过程:

接收过程与发送过程刚好相反,数据报文首先调用ethernet_input()函数到达数据链路层,去掉以太网头部之后如果是ARp报文传给调用arp_input()交给ARp协议处理,如果是Ip报文就调用ip_input()进入Ip层处理,ip_input()函数中比较数据报文的目的Ip地址,如果与某个网络接口的Ip地址相同,则接收这个报文,依照Ip头部的协议字段,调用各自协议的输入处理函数,本例中将调用udp_input(),在udp_input()中提取数据报文的端口号,然后在已登记的套接字中查找与该端口号符合的uDp接收函数,如果没有找到相应的套接字,调用icmp_output()发送一个Icmp不可达报文,如果找到了,就调用该函数(这个函数就是我们在udp_bind()时传入的其中一个参数)。

  udp_input

  处理流程图:

  篇三:

uDp收发机制

  uDp简单聊天程序总结

  任务一:

基于uDp的简单聊天程序实现,采用书上的程序,实现的是客户端发送,服务器端接受,然后发送,如此交替。

即这是一个单线程的程序,不能实现同时进行消息的收发。

  服务器端程序如下:

  //包含进ws2_32.lib库(也可以直接把链接项包含近来,而不使用下面这句代码)

  #pragmacomment(lib,"

ws2_32"

  voidmain()

  {

  //绑定套接字bind(socksrv,(socKADDR*)//创建套接字socKeTsocksrv=socket(AF_IneT,socK_DRAm,0);

socKADDR_Inaddrsrv;

addrsrv.sin_addr.s_un.s_addr=htonl(InADDR_AnY);

addrsrv.sin_family=AF_IneT;

addrsrv.sin_port=htons(6000);

if(LobYTe(wsaData.wVersion)!

=1||}hIbYTe(wsaData.wVersion)!

=1){wsAcleanup();

return;

err=wsAstartup(wVersionRequested,if(err!

=0){}return;

wVersionRequested=mAKewoRD(1,1);

//加载套接字库woRDwVersionRequested;

wsADATAwsaData;

interr;

  charrecvbuf[100];

  }

  while

(1)

  //等待并接收数据recvfrom(socksrv,recvbuf,100,0,(socKADDR*)if(q==recvbuf[0]){}sprintf(tempbuf,"

%ssay:

%s"

inet_ntoa(addrclient.sin_addr),recvbuf);

printf("

%s\n"

tempbuf);

pleaseinputdata:

\n"

);

gets(sendbuf);

sendto(socksrv,sendbuf,strlen(sendbuf)+1,0,(socKADDR*)//关闭套接字closesocket(socksrv);

wsAcleanup();

sendto(socksrv,"

q"

strlen("

)+1,0,(socKADDR*)printf("

chatend!

break;

charsendbuf[100];

chartempbuf[200];

socKADDR_Inaddrclient;

intlen=sizof(socKADDR);

//发送数据

  客户端程序如下:

  //加载套接字库woRDwVersionRequested;

  err=wsAstartup(wVersionRequested,if(err!

=0){}if(LobYTe(wsaData.wVersion)!

=1||}//创建套接字socKeTsockclient=socket(AF_IneT,socK_DgRAm,0);

addrsrv.sin_addr.s_un.s_addr=inet_addr("

192.168.188.114"

charrecvbuf[100];

intlen=sizeof(socKADDR);

while

(1){}//发送数据printf("

sendto(sockclient,sendbuf,strlen(sendbuf)+1,0,(socKADDR*)//等待并接收数据recvfrom(sockclient,recvbuf,100,0,(socKADDR*)if(q==recvbuf[0]){}sprintf(tempbuf,"

inet_ntoa(addrsrv.sin_addr),recvbuf);

sendto(sockclient,"

hIbYTe(wsaData.wVersion)!

  closesocket(sockclient);

  任务二:

在以上程序的基础上作修改,实现同时收发的功能。

这就需要用到多线程的概念。

思路是:

先创建一个互斥对象,然后分别在服务器端和客户端写两个收和发的函数,分别调用waitingforsingleobject函数,以得到这个互斥对象的使用权,等到自己的时间片到了以后再把互斥对象交给另外一个函数。

在程序开始处先声明两个线程的入口函数,在主函数中创建两个线程(主函数本身也是一个线程)。

但是问题在于在主函数中进行套接字的加载,创建,绑定等一系列操作后,主函数后的两个收,发函数无法调用主函数中定义的套接字。

所以在函数开始处就定义套接字,但问题出在下面这两句:

  hThreadReciev=createThread(nuLL,0,(LpThReAD_sTART_RouTIne)recieve,nuLL,0,nuLL);

  hThreadsend=createThread(nuLL,0,(LpThReAD_sTART_RouTIne)sending,nuLL,0,nuLL);

  这两句是正确的,错误的是之前没有把两个收、发函数的起始地址作为createThread函数的第三个参数传给它,所以主函数和另外两个函数之间失去了联系。

  修改后客户端端的程序如下:

  voidrecieve();

  voidsending();

  socKADDR_Inaddrsrv;

  socKeTsockclient;

  intlen;

  if(LobYTe(wsaData.wVersion)!

=1||hIbYTe(wsaData.wVersion)!

woRDwVersionRequested;

  }//创建套接字sockclient=socket(AF_IneT,socK_DgRAm,0);

127.0.0.1"

len=sizeof(socKADDR);

//发送数据hAnDLehThreadReciev,hThreadsend;

hThreadReciev=createThread(nuLL,0,(LpThReAD_sTART_RouTIne)recieve,nuLL,0,nuLL);

hThreadsend=createThread(nuLL,0,(LpThReAD_sTART_RouTIne)sending,nuLL,0,nuLL);

while

(1);

closesocket(sockclient);

  voidrecieve()

  voidsending()

  charsendbuf[100];

while

(1){}

  }gets(sendbuf);

sendto(sockclient,sendbuf,strlen(sendbuf)+1,0,(socKADDR*)charrecvbuf[100];

while

(1){}memset(recvbuf,0,sizeof(recvbuf));

recvfrom(sockclient,recvbuf,100,0,(socKADDR*)if(recvbuf!

=nuLL)puts(recvbuf);

  由此可见,互斥对象并非是必须的,而且入口函数也不是必须要定义。

客户端的程序如下:

  

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 高考

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1