1:基于Socket连接;
2:在四个局域网内测试通过;
3:简单模型,需要进一步优化效率和处理;
基本思路
两个分别在不同的局域网内的用户无法直接建立连接并通讯。因为处在不同局域网的用户(没有公共IP)无法被外部机器主动连接,所以凡是所谓的P2P一般都是通过中间服务器中转通讯的。比如在几年前俺曾经介绍过一个P2P的软件,http://www.cnblogs.com/dlwang2002/archive/2005/04/14/207988.html,基本原理那里面有介绍。
这次所建立的模型,是双方都在不同的局域网内部,都没有公用IP。
基本原理是这样的。局域网A内用户PA想要和局域网B内的用户PB通讯,那么需要通过中间服务器S进行转接通讯。Socket链接虽然只是由一方发起(局域网内的),但是socket确实一个可以在两端都能通讯的,也就是说,PA链接S后,S实际上可以使用这个通道直接发消息给PA。同理,如果PB连接之后,S将有两个Socket实例,然后S可以把SA的消息直接转发给SB,这样SB就转载了SA的请求到了PB。虽然还是要通过中转,但是S只负责把两端Socket互联,速度延时可近似认为是0,也就是可以认为PA和PB是建立了直接的链接,P2P。
过程如下:
1:)PA向S发出连接请求;S接受请求,并且保留住PA的socket实例SA,存进一个在线用户列表LiveConnections中
2:)PB请求S并建立连接(和A无先后关系),S中保存其socket实例SB
3:)PA向s发出通讯请求,指明通讯对象是PB
4:)S接收到A的请求,再当前的LiveConnections中找到PB的socket示例SB,转发消息;
5:)PB接受到来自PA的消息。
主要程序代码
1:)首先的问题是如何建立Socket连接。这个问题在以前的一篇Blog中有提到(http://www.cnblogs.com/dlwang2002/archive/2008/07/21/924803.html)。这里使用的代码基本上都是和那一个一样的,只有中间处理通讯数据的部分稍有不同。这些代码不再赘述。
2:)服务器S处理转发消息的代码
Code
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->1handerdata#regionhanderdata
2try
3{
4Logger.Log("DataReceive",data);//test,catchthedatatransaction
5
6string[]allData=data.Split(';');
7stringrequestTo=allData[0];//thisisthebasicformat:to_IP;from_IP;MSG
8
9//findstoredsocketconnectionhere
10ClientConnectionrequectToCC=null;
11foreach(DictionaryEntrydeinSocketListener.ClientConnections)
12{
13ClientConnectioncc=de.KeyasClientConnection;
14//requestformwillbelikethis"xx.xx.xxx.xxx:xxxxxx",thelastnumberisrunningnumber
15//soif2clientbothinthesamenetwork,thiswillbeconfuedtodispatchthesocket
16//herejustfindthelastonethatinthesamenetwork
17if(cc.RequestFrom.IndexOf(requestTo)>-1)
18{
19requectToCC=cc;
20}
21
22}
23if(requectToCC!=null&&requectToCC.ConSocket.Connected)
24{
25//cangettheconnectionhere,thentransferthisrequesttoit
26try
27{
28ReplayMsg(requectToCC.ConSocket,data);
29}
30catch(Exceptionce)
31{
32ReplayMsg(this.ConSocket,"processerror:"+ce.Message);
33Logger.Log("SendMsgError",ce.Message);
34}
35}
36else
37{
38//ifcannotfind,meansthereqeusttoisnotlogin/registerthere
39ReplayMsg(this.ConSocket,"theclientyourequesttoisdisconnected");
40Logger.Log("SendMsgError","theclientyourequesttoisdisconnected");
41}
42//
43}
44catch(Exceptionex)
45{
46Logger.Log("DataError"+_requestFrom,ex.Message);
47}
48#endregion
3:)客户端的简单实现
ConnectionManager
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->1namespaceP2PClient
2{
3publicclassConnectionManager
4{
5privateSocket_socket;
6privateIPEndPoint_hostEP;
7privatestring_localIP;
8
9publicdelegatevoidMessageReceiveEvent(stringfromIP,stringmsg);
10
11publiceventMessageReceiveEventOnMsgReceived;
12
13publicConnectionManager(stringip,intport)
14{
15IPAddressaddress=IPAddress.Parse(ip);
16_hostEP=newIPEndPoint(address,port);
17}
18
19publicboolConnect2Server()
20{
21try
22{
23_socket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
24_socket.Connect(_hostEP);
25
26IPHostEntryoIPHost=Dns.Resolve(Environment.MachineName);
27_localIP=oIPHost.AddressList[0].ToString();
28
29//thereusethesamesocket,towaitforreplymsg
30Threadthread=newThread(newThreadStart(WaitForReceiveData));
31thread.Name="connection_";
32thread.Start();
33
34returntrue;
35}
36catch(Exceptionex)
37{
38returnfalse;
39}
40}
41publicvoidClose()
42{
43_socket.Shutdown(SocketShutdown.Both);
44_socket.Close();
45}
46publicvoidSendMessage(stringclientIP,stringmsg)
47{
48stringsendStr=clientIP+";"+_localIP+";"+msg;//simpleformat;to_IP;from_IP;MSG
49
50byte[]bytesSendStr=newbyte[1024];
51bytesSendStr=Encoding.ASCII.GetBytes(sendStr);
52_socket.Send(bytesSendStr,bytesSendStr.Length,0);
53}
54
55publicvoidWaitForReceiveData()
56{
57byte[]bytes=newByte[1024];
58
59while(true)
60{
61bytes=newbyte[1024];
62stringdata="";
63
64//thesystemwhilebewaithereuntilthereismsgreceivedhere
65intbytesRec=this._socket.Receive(bytes);
66
67data+=Encoding.ASCII.GetString(bytes,0,bytesRec);
68#regionhanderdata
69Logger.Log("DataReceive",data);
70
71string[]allData=data.Split(';');
72stringrequestFrom=allData[1];//thisisthebasicformat;to_IP;from_IP;MSG
73stringmsg=allData[2];
74
75if(OnMsgReceived!=null)
76{
77OnMsgReceived(requestFrom,msg);
78}
79#endregion
80}
81}
82
83
84}
4:)UI等其他处理 (略)
问题
1:)一个Socket的实例可以在服务器/客户端存活多久呢?我测试发现,至少几个小时没有问题,但是最长时间却不知道。
2:)服务器S用单独的线程来处理链接,并不是最好的方式
3:)服务器负载平衡,在多个服务器的情况下,要让客户端可以选择效率最高的服务器进行中转
4:)有一台机器已经在公网上,或者两台都在公网上,需要另外的模型。他们不需要中转。
小结
简单,效率未知。
分享到:
相关推荐
C#编写的P2P Socket,实现内网穿透,匿名网络资源的获取等,代码异步实现各种操作,供大家学习参考
p2p C# socket 多人聊天系统 p2p C# socket 多人聊天系统 p2p C# socket 多人聊天系统 打洞技术
p2p实例代码。对P2P开发有很好的作用呀。大家可以学习下。
帮助你怎样实现socket编程的最有效资源。内涵C#源码。Java源码。C源码。
C#,基于UDP的Socket通信客户端,包含服务器端和客户端,有图形化界面,通过服务器IP连接,点对点通信,不支持一对多,功能上属于很简单的,演示和理解基于UDP的Socket通信原理有一定的帮助。
sockesockesockesockesockesockesockesockesockesockev
服务器与客户端的程序都有 采用异步回调方式写的P2P程序
C#,基于TCP/IP的Socket通信客户端,包含服务器端和客户端,有图形化界面,通过服务器IP连接,是异步通信,非同步通信,点对点通信,不支持一对多,功能上属于很简单的,演示和理解基于TCP/IP的Socket通信原理有一定...
第六章 网络应用 实例1 Socket建立服务器程序 实例2 Socket建立客户端程序 实例3 P2P技术实现点对点聊天 实例4 C/S聊天模型 实例5 Ftp服务器端实现 实例6 Ftp客户端实现
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的...本程序基于TCP编程,多线程、监听服务、Socket套接字,实现网络通讯聊天。 VS2010环境测试通过,希望对你学习帮助有用。
(1)介绍C/S(Windows窗体)多进程、多线程编程技术包括:进程调用、查看、... 主要介绍TCP、UDP、SMTP、FTP、P2P (4)介绍数据加密、解密技术。 包括网络数据加密与数字签名。 (5)介绍一个网络综合应用开发实例
这是用C#语言写的P2P的一个数据传输软件,附带源代码,message 、单个文件以及文件夹的传输算法都有。
该软件实现了p2p的多种功能,包括聊天 传送文件,传送图片等功能,实际效果跟qq差不多,适合于本科生的毕业设计
多线程 ,应用Socket类实现P2P聊天.通过服务端与客户端两个对等的窗体,实现类似QQ的聊天效果。通过多线程,实现发送请求后不用等待响应,就可以继续发送请求,类似QQ。发送的消息都能及时显示在两个窗体的listBox中...
C# Socket 点对点聊天程序实例,我用VS2005写的
这个程序可以建立服务器与客户端的连接,并相互接受发送内容。用C#实现的
基于P2P的局域网即时通信系统+项目说明(c#源码)计算机网络课程设计.zip 基于P2P的局域网即时通信系统+项目说明(c#源码)计算机网络课程设计.zip 基于P2P的局域网即时通信系统+项目说明(c#源码)计算机网络课程设计.zip...
1.3.1 Socket类 1.3.2 面向连接的套接字 1.3.3 无连接的套接字 1.4 网络流 习题 第2章 TCP应用编程 2.1 同步TCP应用编程 2.1.1 使用套接字发送和接收数据 2.1.2 使用NetworkStream...
1.3.1 Socket类 20 1.3.2 面向连接的套接字 21 1.3.3 无连接的套接字 23 1.4 网络流 24 1.5 习题1 25 第2章 TCP应用编程 27 2.1 同步TCP应用编程 28 2.1.1 使用套接字发送和接收数据 28 2.1.2 使用NetworkStream对象...
实例6 在SQL Server中存储显示图片 实例7 在ACESS 2000中存储显示图片 第六章 网络应用 实例1 Socket建立服务器程序 实例2 Socket建立客户端程序 实例3 P2P技术实现点对点聊天 实例4 C/S...