SOCKET DUP 使用心得.docx

上传人:A*** 文档编号:141375822 上传时间:2020-08-07 格式:DOCX 页数:4 大小:13.24KB
返回 下载 相关 举报
SOCKET DUP 使用心得.docx_第1页
第1页 / 共4页
SOCKET DUP 使用心得.docx_第2页
第2页 / 共4页
SOCKET DUP 使用心得.docx_第3页
第3页 / 共4页
SOCKET DUP 使用心得.docx_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《SOCKET DUP 使用心得.docx》由会员分享,可在线阅读,更多相关《SOCKET DUP 使用心得.docx(4页珍藏版)》请在金锄头文库上搜索。

1、SOCKET DUP 使用心得1、客户端绑定端口的问题对于UDP,客户端不需要调用BIND绑定本机地址和端口,即便是绑定了本机地址,服务器也不能从这个绑定的端口发送过来信息,因为到路由器就会被丢弃,本机是根本接不到的,那客户端如何接收服务器端的信息呢,这就是服务器端recvfrom()的作用了,服务器端在接收的时候,最后两个参数就是客户端OS给临时分配的一个sockaddr结构体,里面包含要通信的客户端地址跟端口信息,对于发送到这个地址和端口的消息,路由是不拦的,对于为什么上一个拦,而这个又不拦呢,这是因为上一个消息是不请自来的,路由会将其当成攻击消息,将其丢弃,而下一个则是客户端先发送的,而

2、后服务器跟据这个端口发送的消息则会被路由器当成回复消息,而不会拦截。2、客户端使用创建线程来接收来自服务器的信息平时我们一般会将接收信息的while(true)超级循环独自封装到一个线程中,但有个问题要注意一下,就是,在客户端由于不能像服务器那样运行,也就说,在客户端是不能接收随便发过来的信息的,所以如果我们在recvfrom()之前,没有提前调用sendto()的话,程序会报错!在运行到recvfrom()时,一直报10022的错误,即参数不对或第一个参数SOCKET没配置正确,这个错误是很难找到的,它的主要原因就是recvfrom()了一个不确定的地址和端口,即sockaddr_in参数不

3、对,虽然写得是服务器的地址和端口,但它并不认识。这里我写了个小例子,VC+ 2008 控制台应用程序。大家可以下载下面只贴出部分代码:这个是客户端的接收线程:DWORD WINAPI RecvServerThreadProc(LPVOID lpParameter) char recvBuf128; memset(recvBuf,0,128); while(true) if(SOCKET_ERROR=recvfrom(sserver,recvBuf,128,0,(sockaddr*)&Server_addr_in,&sockaddr_len) int lastError=WSAGetLastEr

4、ror(); printf(recv error;%d,lastError); else char* ipSvr = inet_ntoa(Server_addr_in.sin_addr); printf(%s said: %s/n,ipSvr,recvBuf); _tmain()里的创建线程代码:/创建服务器消息接收线程 string str=登陆成功!; strcpy(sendBuf,str.c_str(); if(SOCKET_ERROR =sendto(sserver,sendBuf,strlen(sendBuf)+1,0,(sockaddr*)&Server_addr_in,socka

5、ddr_len) printf(send error!); /这里先向SERVER发送信息,再再创建线程,这样才不会报错 else printf(send success); HANDLE threadhandle = CreateThread(NULL, 0, RecvServerThreadProc, NULL, 0, NULL); CloseHandle(threadhandle);/释放句柄资源,放弃对句柄的引用完整源码下载地址:http:/ sockaddr的长度,因为在recvfrom的实现中将会用到这个值。对于recvform:int len = sizeof(sockaddr)

6、;recvfrom(xxxx,xxxx,xxx,0,(sockaddr*)&addr_in,&len);对于sendto:int len = sizeof(sockaddr);sendto(xxx,xxx,xxx,0,(sockaddr*)&addr_in,len)4、网络字节序绑定转换总结本机字节顺序与网络字节顺序的转换htons-host to network shorthtonl -host to network longntohs -network to host short /用于转换端口ntohl -network to host longSockaddr_in相关/初始化IP地址

7、:Sockaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);/这个一般用过初始化服务器监听地址Sockaddr.sin_addr.s_addr =inet_addr(222.195.151.20);/这个一般用于初始化客户端发送时的服务器的IP地址/初始化端口Sockaddr.sin_port= htons(600000);5、sendto()消息使用结构体注意:使用这种方法能转换成功的关键点在于:1、使用一字节对齐2、结构体的各成员的大小是固定的,这里不能使用不固定大小的成员参数如:string info;这样在转换的时候会出错,要么乱码,要么没有信

8、息,出错的原因在于,发送的信息与接收的信息无法实现字节对齐!定义的结构体如下:struct send_infochar info_from20; /发送者IDchar info_to20; /接收者IDint info_length; /发送的消息主体的长度char info_content1024; /消息主体;发送端主要代码(为了简洁说明问题,我把用户输入的内容、长度等验证的代码去掉了):struct send_info info1; /定义结构体变量printf(This is client,please input message:);/从键盘读取用户输入的数据,并写入info1.in

9、fo_contentmemset(info1.info_content,0,sizeof(info1.info_content);/清空缓存info1.info_length=read(STDIN_FILENO,info1.info_content,1024) - 1;/读取用户输入的数据memset(snd_buf,0,1024);/清空发送缓存,不清空的话可能导致接收时产生乱码,/或者如果本次发送的内容少于上次的话,snd_buf中会包含有上次的内容memcpy(snd_buf,&info1,sizeof(info1); /结构体转换成字符串send(connect_fd,snd_buf,

10、sizeof(snd_buf),0);/发送信息接收端主要代码:struct send_info clt; /定义结构体变量memset(recv_buf,z,1024);/清空缓存recv(fd,recv_buf,1024,0 );/读取数据memset(&clt,0,sizeof(clt);/清空结构体memcpy(&clt,recv_buf,sizeof(clt);/把接收到的信息转换成结构体clt.info_contentclt.info_length=;/消息内容结束,没有这句的话,可能导致消息乱码或输出异常/有网友建议说传递的结构体中尽量不要有string类型的字段,估计就是串尾符定位的问题if(clt.info_content) /判断接收内容并输出printf(nclt.info_from is %snclt.info_to is %snclt.info_content is%snclt.info_length is %dn,clt.info_from,clt.info_to,clt.info_content,clt.info_length);/至此,结构体的发送与接收已经顺利结束了

展开阅读全文
相关资源
相关搜索

当前位置:首页 > IT计算机/网络 > 其它相关文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号