大坡3D软件开发

关注3D软件技术

用户操作
[即时聊天] [发私信] [加为好友]
蔡军生ID:caimouse
1252430次访问,排名17好友253人,关注者432
C++,3D,VC++软件开发,写技术文章,操作系统开发
caimouse的文章
原创 604 篇
翻译 0 篇
转载 41 篇
评论 946 篇
蔡军生的公告

点击这里给我发消息

MSN: caimouse1976 at sina.com

最近评论
firefly_liu:我用VS2008怎么打不开工程啊,需要怎么配置吗
allenemo:鸡儿屎吃多了,找鸡儿不到牛批吹!
orichisonic:还是支持军生大哥,觉得这几篇写的很详实的
holon:不错,支持一下

------------------------------
www.arraylist.cn cn域名免费送
IT人的酒吧式交流平台
-----------------------------
fhchina:强烈建议博主分析一下WebKit的源码架构,Chrome这种UI前端框架代码有什么好分析的????浪费时间而已。
文章分类
收藏
相册
3D引擎
第二人生
谷歌浏览器
开发板
历史回忆
常用连接
人生历程
存档
软件项目交易
订阅我的博客
XML聚合  FeedSky

原创 第二人生的源码分析(二十六)底层网络协议收藏

新一篇: 第二人生的源码分析(二十七)发送数据的流量控制 | 旧一篇: 我的编程之路(三)

为了理解第二人生的客户端与服务器的沟通,那么下面就来分析一下第二人生采用的网络协议。在目前的网络里,主要有两个协议:TCP和UDP,而第二人生里是采用UDP协议。TCP协议与UDP协议的主要区别,就是TCP有流量控制,可靠性控制,IP层组包功能,连接需要三次握手,而UDP没有这些保证,因此UDP发送的数据包需要自己来管理数据的有序性和可靠性。先来分析最底层的协议,它调用UDP发送数据的源码如下:
#001 // Returns TRUE on success.
#002 BOOL send_packet(int hSocket, const char *sendBuffer, int size, U32 recipient, int nPort)
#003 {
#004      // Sends a packet to the address set in initNet
#005      // 
#006      int nRet = 0;
#007      U32 last_error = 0;
#008 
#009      stDstAddr.sin_addr.s_addr = recipient;
#010      stDstAddr.sin_port = htons(nPort);
#011      do
#012      {
#013             nRet = sendto(hSocket, sendBuffer, size, 0, (struct sockaddr*)&stDstAddr, sizeof(stDstAddr));                
#014     
#015 
#016             if (nRet == SOCKET_ERROR )
#017             {
#018                    last_error = WSAGetLastError();
#019                    if (last_error != WSAEWOULDBLOCK)
#020                    {
#021                           // WSAECONNRESET - I think this is caused by an ICMP "connection refused"
#022                           // message being sent back from a Linux box... I'm not finding helpful
#023                           // documentation or web pages on this. The question is whether the packet
#024                           // actually got sent or not. Based on the structure of this code, I would
#025                           // assume it is. JNC 2002.01.18
#026                           if (WSAECONNRESET == WSAGetLastError())
#027                           {
#028                                  return TRUE;
#029                           }
#030                           llinfos << "sendto() failed to " << u32_to_ip_string(recipient) << ":" << nPort
#031                                  << ", Error " << last_error << llendl;
#032                    }
#033             }
#034      } while ( (nRet == SOCKET_ERROR)
#035                     &&(last_error == WSAEWOULDBLOCK));
#036 
#037      return (nRet != SOCKET_ERROR);
#038 }
 
在13行里调用WINDOWS API函数sendto来发送数据sendBuffer到目标地址stDstAddr里,这样就可以把数据交给WINDOWS的网络去发送数据了。由于这里采用异步的UDP来发送数据,因此采用了一个do while来处理正在阻塞的情况。当发送不成功,并且错误码是WSAEWOULDBLOCK,说明WINDOWS API正在发送过程中,不能接收数据,这样就循环地检查,直到发送成功,或者出错为止。第二人生里跟服务器发送的消息,就是这样发送出去的,看起来比较简单吧。
 蔡军生 2008/3/20 QQ:9073204 深圳
 

发表于 @ 2008年03月20日 21:59:00|评论(loading...)|编辑

新一篇: 第二人生的源码分析(二十七)发送数据的流量控制 | 旧一篇: 我的编程之路(三)

评论:没有评论。

发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © 蔡军生