ImageVerifierCode 换一换
格式:DOCX , 页数:18 ,大小:30.29KB ,
资源ID:11814196      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/11814196.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(udp中socket的用法.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

udp中socket的用法.docx

1、udp中socket的用法struct sockaddr unsigned short sa_family; char sa_data14; ; 上面是通用的socket地址,此数据结构用做bind、connect、recvfrom、sendto等函数的参数,指明地址信息。具体到Internet socket,用下面的结构,二者可以进行类型转换。 struct sockaddr_in short int sin_family; unsigned short int sin_port; struct in_addr sin_addr; unsigned char sin_zero8; ;stru

2、ct in_addr就是32位IP地址。struct in_addr union struct u_char s_b1,s_b2,s_b3,s_b4; S_un_b; struct u_short s_w1,s_w2; S_un_w; u_long S_addr; S_un;#define s_addr S_un.S_addr ; in_addr()是将一个点分制的IP地址(如192.168.0.1)转换为上述结构中需要的32位IP地址(0xC0A80001)。通常的用法是: int sockfd; struct sockaddr_in my_addr; sockfd= socket(AF_I

3、NET, SOCK_STREAM, 0); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(MYPORT); my_addr.sin_addr.s_addr = inet_addr(192.168.0.1); bzero(&(my_addr.sin_zero), 8); bind(sockfd, (struct sockaddr*)&my_addr, sizeof(structsockaddr);sa_family是地址家族,一般都是“AF_xxx”的形式。通常大多用的是都是AF_INET,代表TCP/IP协议族。sa_data 是

4、14字节协议地址。sin_family指代协议族,在socket编程中只能是AF_INETsin_port存储端口号(使用网络字节顺序)sin_addr存储IP地址,使用in_addr这个数据结构sin_zero是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。sockaddr_in和sockaddr是并列的结构,指向sockaddr_in的结构体的指针也可以指向 sockaddr的结构体,并代替它。也就是说,你可以使用sockaddr_in建立你所需要的信息, 然后用进行类型转换就可以了bzero(char*)&mysock,sizeof(mysock)

5、;sin_zero 初始值应该使用函数 bzero() 来全部置零。最典型的源、目的节点socket定义对于源、目的地址和源、目的地址端口,需要建立两个socket变量cliaddr绑定源地址和源端口。servaddr用于connect和sendto的设定目的地址和目的端口。struct sockaddr_in servaddr,cliaddr;create_socket(char *server_addr_string,unsigned int server_port)源socket赋值bzero(&cliaddr,sizeof(cliaddr);cliaddr.sin_family = A

6、F_INET;通常TCP/UDP 协议源地址和端口都是随机的cliaddr.sin_addr.s_addr = htons(INADDR_ANY);cliaddr.sin_port = htons(0);目的socket赋值bzero(&servaddr,sizeof(servaddr);servaddr.sin_family = AF_INET;inet_aton(server_addr_string,&servaddr.sin_addr);servaddr.sin_port = htons(server_port);NBO,HBO二者转换inet_addr()将字符串点数格式地址转化成无

7、符号长整型(unsigned long s_addr s_addr;)inet_aton()将字符串点数格式地址转化成NBOinet_ntoa () 将NBO地址转化成字符串点数格式htons()Host to Network Shorthtonl()Host to Network Longntohs()Network to Host Shortntohl()Network to Host Long常用的是htons(),inet_addr()正好对应结构体的端口类型和地址类型三种给socket赋值地址的方法inet_aton(server_addr_string,&myaddr.sin_ad

8、dr);myaddr.sin_addr.s_addr = inet_addr(132.241.5.10);myaddr.sin_addr.s_addr = htons(INADDR_ANY);两种给socket 赋值端口的方法#define MYPORT 3490myaddr.sin_port = htons(MYPORT);0(随机端口)myaddr.sin_port = htons(0);3.1创建套接字socket() 应用程序在使用套接字前,首先必须拥有一个套接字,系统调用socket()向应用程序提供创建套接字的手段3.2指定本地地址bind() 当一个套接字用socket()创建后

9、,存在一个名字空间(地址族),但它没有被命名。bind()将套接字地址(包括本地主机地址和本地端口地址)与所创建的套接字号联系起来,即将名字赋予套接字,以指定本地半相关。3.3建立套接字连接connect()与accept() 这两个系统调用用于完成一个完整相关的建立,其中connect()用于建立连接。无连接的套接字进程也可以调用connect(),但这时在进程之间没有实际的报文交换,调用将从本地操作系统直接返回。这样做的优点是程序员不必为每一数据指定目的地址,而且如果收到的一个数据报,其目的端口未与任何套接字建立“连接”,便能判断该端靠纪 纪 可操作。而accept()用于使服务器等待来自

10、某客户进程的实际连接3.4监听连接listen() 此调用用于面向连接服务器,表明它愿意接收连接。listen()需在accept()之前调用3.5数据传输send()与recv() 当一个连接建立以后,就可以传输数据了。常用的系统调用有send()和recv()。3.6输入/输出多路复用select() select()调用用来检测一个或多个套接字的状态。对每一个套接字来说,这个调用可以请求读、写或错误状态方面的信息。请求给定状态的套接字集合由一个fd_set结构指示。在返回时,此结构被更新,以反映那些满足特定条件的套接字的子集,同时,select()调用返回满足条件的套接字的数目3.7关闭

11、套接字closesocket() closesocket()关闭套接字s,并释放分配给该套接字的资源;如果s涉及一个打开的TCP连接,则该连接被释放。/*建立套接字*/ Socket()sock=socket(AF_INET,SOCK_STREAM,0); if(sock0) perror(“openingstreamsocket”); exit(1); /*设置套接口的选项。*/Setsockopt()通讯的基石是套接口,一个套接口是通讯的一端。在这一端上你可以找到与其对应的一个名字。一个正在被使用的套接口都有它的类型和与其相关的进程。套接口存在于通讯域中。通讯域是为了处理一般的线程通过套接

12、口通讯而引进的一种抽象概念。 int PASCAL FAR setsockopt( SOCKET s, int level, int optname, const char FAR *optval,int optlen); s:标识一个套接口的描述字。 level:选项定义的层次;目前仅支持SOL_SOCKET和IPPROTO_TCP层次。 optname:需设置的选项。 optval:指针,指向存放选项值的缓冲区。 optlen:optval缓冲区长度。有两种套接口的选项:一种是布尔型选项,允许或禁止一种特性;另一种是整形或结构选项。允许一个布尔型选项,则将optval指向非零整形数;禁止一

13、个选项optval指向一个等于零的整形数。对于布尔型选项,optlen应等于sizeof(int);对其他选项,optval指向包含所需选项的整形数或结构,而optlen则为整形数或结构的长度若无错误发生,setsockopt()返回0。否则的话,返回SOCKET_ERROR错误缺省条件下,一个套接口不能与一个已在使用中的本地地址捆绑(参见bind())。但有时会需要“重用”地址。因为每一个连接都由本地地址和远端地址的组合唯一确定,所以只要远端地址不同,两个套接口与一个地址捆绑并无大碍。为了通知WINDOWS套接口实现不要因为一个地址已被一个套接口使用就不让它与另一个套接口捆绑,应用程序可在b

14、ind()调用前先设置SO_REUSEADDR选项。请注意仅在bind()调用时该选项才被解释;故此无需(但也无害)将一个不会共用地址的套接口设置该选项,或者在bind()对这个或其他套接口无影响情况下设置或清除这一选项。 一个应用程序可以通过打开SO_KEEPALIVE选项,使得WINDOWS套接口实现在TCP连接情况下允许使用“保持活动”包。一个WINDOWS套接口实现并不是必需支持“保持活动”,但是如果支持的话,具体的语义将与实现有关如果有关连接由于“保持活动”而失效,则进行中的任何对该套接口的调用都将以WSAENETRESET错误返回,后续的任何调用将以WSAENOTCONN错误返回。

15、setsockopt()支持下列选项。其中“类型”表明optval所指数据的类型。 选项 类型 意义 SO_BROADCAST BOOL 允许套接口传送广播信息。 SO_DEBUG BOOL 记录调试信息。 SO_DONTLINER BOOL 不要因为数据未发送就阻塞关闭操作。设置本选项相当于将SO_LINGER的l_onoff元素置为零。 SO_DONTROUTE BOOL 禁止选径;直接传送。 SO_KEEPALIVE BOOL 发送“保持活动”包。 SO_LINGER struct linger FAR* 如关闭时有未发送数据,则逗留。 SO_OOBINLINE BOOL 在常规数据流中

16、接收带外数据。 SO_RCVBUF int 为接收确定缓冲区大小。 SO_REUSEADDR BOOL 允许套接口和一个已在使用中的地址捆绑(参见bind())。 SO_SNDBUF int 指定发送缓冲区大小。 TCP_NODELAY BOOL 禁止发送合并的Nagle算法。bind()将一本地地址与一套接口捆绑。本函数适用于未连接的数据报或流类套接口,在connect()或listen()调用前使用。当用socket()创建套接口后,它便存在于一个名字空间(地址族)中,但并未赋名。bind()函数通过给一个未命名套接口分配一个本地名字来为套接口建立本地捆绑(主机地址/端口号)。将一本地地址

17、与一套接口捆绑。 #include int PASCAL FAR bind( SOCKET s, const struct sockaddr FAR* name, int namelen); s:标识一未捆绑套接口的描述字。 name:赋予套接口的地址。 namelen:name名字的长度。如无错误发生,则bind()返回0。否则的话,将返回SOCKET_ERROR,应用程序可通过WSAGetLastError()获取相应错误代码。Recvfrom()recvfrom函数(经socket接收数据): 函数原型:int recvfrom(int sockfd,void *buf,int len,

18、unsigned int flags,struct sockaddr *from,int *fromlen); 函数说明:recv()用来接收远程主机经指定的socket传来的数据,并把数据传到由参数buf指向的内存空间,参数len为可接收数据的最大长度.参数flags一般设0,其他数值定义参考recv().参数from用来指定欲传送的网络地址,结构sockaddr请参考bind()函数.参数fromlen为sockaddr的结构长度.返回值:成功则返回接收到的字符数,失败返回-1.inet_ntoa_b()inet_ntoa_b() - convert an network address

19、to dot notation, store it in a buffervoid inet_ntoa_b ( struct in_addr inetAddress, /* inet address */ char * pString /* where to return ASCII string */ )This routine converts an Internet address in network format to dotted decimal notation. This routine is identical to the UNIX inet_ntoa() routine

20、except that you must provide a buffer of size INET_ADDR_LEN. ntohs()简述: 将一个无符号短整形数从网络字节顺序转换为主机字节顺序。 #include u_short PASCAL FAR ntohs( u_short netshort); netshort:一个以网络字节顺序表达的16位数。 本函数将一个16位数由网络字节顺序转换为主机字节顺序。 返回值: ntohs()返回一个以主机字节顺序表达的数。 inet_ntoa() 将网络地址转换成“.”点隔的字符串格式。 #include char FAR* PASCAL FAR

21、 inet_ntoa( struct in_addr in); in:一个表示Internet主机地址的结构。 本函数将一个用in参数所表示的Internet地址结构转换成以“.” 间隔的诸如“a.b.c.d”的字符串形式。请注意inet_ntoa()返回的字符串存放在WINDOWS套接口实现所分配的内存中。应用程序不应假设该内存是如何分配的。在同一个线程的下一个WINDOWS套接口调用前,数据将保证是有效。inet_addr()功能:字符串转地址 inet_addr( const struct FAR* cp); cp:一个以Internet标准“.”间隔的字符串。本函数解释cp参数中的字符

22、串,这个字符串用Internet的“.”间隔格式表示一个数字的Internet地址。返回值可用作Internet地址。所有Internet地址以网络字节顺序返回(字节从左到右排列)。htons ()u_short PASCAL FAR htons( u_short hostshort); htons的功能:将一个无符号短整型数值转换为网络字节序,即大端模式(big-endian) 参数u_short hostshort: 16位无符号整数 返回值:TCP / IP网络字节顺序. htons 是把你机器上的整数转换成“网络字节序”, 网络字节序是 big-endian,也就是整数的高位字节存放在

23、内存的低地址处。 而我们常用的 x86 CPU (intel, AMD) 电脑是 little-endian,也就是整数的低位字节放在内存的低字节处。sendto()int PASCAL FAR sendto( SOCKET s, const char FAR* buf,int len, int flags, const struct sockaddr FAR* to, int tolen); s:一个标识套接口的描述字。 buf:包含待发送数据的缓冲区。 len:buf缓冲区中数据的长度。 flags:调用方式标志位。 to:(可选)指针,指向目的套接口的地址。 tolen:to所指地址的长

24、度。请注意成功地完成sendto()调用并不意味着数据传送到达。 sendto()函数主要用于SOCK_DGRAM类型套接口向to参数指定端的套接口发送数据报。对于SOCK_STREAM类型套接口,to和tolen参数被忽略;这种情况下sendto()等价于send()。 为了发送广播数据(仅适用于SOCK_DGRAM),in参数所含地址应该把特定的IP地址INADDR_BROADCAST(winsock.h中有定义)和终端地址结合起来构造。通常建议一个广播数据报的大小不要大到以致产生碎片,也就是说数据报的数据部分(包括头)不超过512字节。 若无错误发生,send()返回所发送数据的总数(请

25、注意这个数字可能小于len中所规定的大小)。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。UDP协议的主要作用是将网络数据流量压缩成数据包的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。数据报的长度是指包括报头和数据部分在内的总字节数。因为报头的长度是固定的,所以该域主要被用来计算可变长度的数据部分(又称为数据负载)。UDP协议使用报头中的校验值来保证数据的安全。校验值首先在数据发送方通过特殊的算法计算得出,在传递到接收方之后,还需要再重新计算。如果

26、某个数据报在传输过程中被第三方篡改或者由于线路噪音等原因受到损坏,发送和接收方的校验计算值将不会相符,由此UDP协议可以检测是否出错。这与TCP协议是不同的,后者要求必须具有校验值。UDP和TCP协议的主要区别是两者在如何实现信息的可靠传递方面不同。TCP协议中包含了专门的传递保证机制,当数据接收方收到发送方传来的信息时,会自动向发送方发出确认消息;发送方只有在接收到该确认消息之后才继续传送其它信息,否则将一直等待直到收到确认信息为止。 与TCP不同,UDP协议并不提供数据传送的保证机制。如果在从发送方到接收方的传递过程中出现数据报的丢失,协议本身并不能做出任何检测或提示。因此,通常人们把UD

27、P协议称为不可靠的传输协议。UDP具有TCP所望尘莫及的速度优势。虽然TCP协议中植入了各种安全保障功能,但是在实际执行的过程中会占用大量的系统开销,无疑使速度受到严重的影响。反观UDP由于排除了信息可靠传递机制,将安全和排序等功能移交给上层应用来完成,极大降低了执行时间,使速度得到了保证。UDP程序:包括server和client两部分1、编写UDP Server程序的步骤(1)使用socket()来建立一个UDP socket,第二个参数为SOCK_DGRAM。(2)初始化sockaddr_in结构的变量,并赋值。sockaddr_in结构定义: struct in_addr in_add

28、r_t s_addr; ; 结构体 in_addr 用来表示一个32位的IPv4地址. in_addr_t 一般为 32位的unsigned long. 其中每8位代表一个IP地址位中的一个数值. 例如192.168.3.144记为0xc0a80390,其中 c0 为192 ,a8 为 168, 03 为 3 , 90 为 144 。 struct sockaddr_in uint8_t sin_len; sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; char sin_zero8; ;(3)使用bind

29、()把上面的socket和定义的IP地址和端口绑定。这里检查bind()是否执行成功,如果有错误就退出。这样可以防止服务程序重复运行的问题。(4)进入无限循环程序,使用recvfrom()进入等待状态,直到接收到客户程序发送的数据,就处理收到的数据,并向客户程序发送反馈。这里是直接把收到的数据发回给客户程序。udpserv.c程序内容 #include #define MAXLINE 80 #define SERV_PORT 8888 void do_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen) int n ; socklen_t len ; char mesgMAXLINE ; for(;) len = clilen; /* waiting for receive data */ n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len); sendto(sockfd, mesg, n, 0, pcliaddr, le

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

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