`

P2P通讯初步实现(c#,Socket连接)

 
阅读更多

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,也就是可以认为PAPB是建立了直接的链接,P2P

过程如下:

1:)PAS发出连接请求;S接受请求,并且保留住PAsocket实例SA,存进一个在线用户列表LiveConnections

2:)PB请求S并建立连接(和A无先后关系),S中保存其socket实例SB

3:)PAs发出通讯请求,指明通讯对象是PB

4:)S接收到A的请求,再当前的LiveConnections中找到PBsocket示例SB,转发消息;

5:)PB接受到来自PA的消息。

主要程序代码

1:)首先的问题是如何建立Socket连接。这个问题在以前的一篇Blog中有提到(http://www.cnblogs.com/dlwang2002/archive/2008/07/21/924803.html)。这里使用的代码基本上都是和那一个一样的,只有中间处理通讯数据的部分稍有不同。这些代码不再赘述。

2:)服务器S处理转发消息的代码



<!--<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:)客户端的简单实现


<!--<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:)有一台机器已经在公网上,或者两台都在公网上,需要另外的模型。他们不需要中转。

小结

简单,效率未知。
server.jpg
client.jpg

分享到:
评论

相关推荐

    用C#实现的P2P Socket源代码

    C#编写的P2P Socket,实现内网穿透,匿名网络资源的获取等,代码异步实现各种操作,供大家学习参考

    p2p C# socket 聊天系统

    p2p C# socket 多人聊天系统 p2p C# socket 多人聊天系统 p2p C# socket 多人聊天系统 打洞技术

    c#p2p(socket)

    p2p实例代码。对P2P开发有很好的作用呀。大家可以学习下。

    socket编程 P2P

    帮助你怎样实现socket编程的最有效资源。内涵C#源码。Java源码。C源码。

    C#_UDP_Socket_P2P_通信客户端.zip

    C#,基于UDP的Socket通信客户端,包含服务器端和客户端,有图形化界面,通过服务器IP连接,点对点通信,不支持一对多,功能上属于很简单的,演示和理解基于UDP的Socket通信原理有一定的帮助。

    c# socket p2p doc

    sockesockesockesockesockesockesockesockesockesockev

    C#异步回调Socket P2P编程

    服务器与客户端的程序都有 采用异步回调方式写的P2P程序

    C#_异步TCP_IP_Socket_P2P_通信客户端.zip

    C#,基于TCP/IP的Socket通信客户端,包含服务器端和客户端,有图形化界面,通过服务器IP连接,是异步通信,非同步通信,点对点通信,不支持一对多,功能上属于很简单的,演示和理解基于TCP/IP的Socket通信原理有一定...

    第6章 C#网络开发,p2p,聊天,socket

    第六章 网络应用 实例1 Socket建立服务器程序 实例2 Socket建立客户端程序 实例3 P2P技术实现点对点聊天 实例4 C/S聊天模型 实例5 Ftp服务器端实现 实例6 Ftp客户端实现

    C#TCP网络通讯

    TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的...本程序基于TCP编程,多线程、监听服务、Socket套接字,实现网络通讯聊天。 VS2010环境测试通过,希望对你学习帮助有用。

    C# Socket网络应用编程

    (1)介绍C/S(Windows窗体)多进程、多线程编程技术包括:进程调用、查看、... 主要介绍TCP、UDP、SMTP、FTP、P2P (4)介绍数据加密、解密技术。 包括网络数据加密与数字签名。 (5)介绍一个网络综合应用开发实例

    C#语言写的P2P的一个数据传输软件——飞鸽传书.net

    这是用C#语言写的P2P的一个数据传输软件,附带源代码,message 、单个文件以及文件夹的传输算法都有。

    C#下实现p2p聊天软件

    该软件实现了p2p的多种功能,包括聊天 传送文件,传送图片等功能,实际效果跟qq差不多,适合于本科生的毕业设计

    多线程 P2P 实现QQ聊天效果

    多线程 ,应用Socket类实现P2P聊天.通过服务端与客户端两个对等的窗体,实现类似QQ的聊天效果。通过多线程,实现发送请求后不用等待响应,就可以继续发送请求,类似QQ。发送的消息都能及时显示在两个窗体的listBox中...

    C#点对点P2P聊天实例

    C# Socket 点对点聊天程序实例,我用VS2005写的

    socKet的简单实现

    这个程序可以建立服务器与客户端的连接,并相互接受发送内容。用C#实现的

    基于P2P的局域网即时通信系统+项目说明(c#源码)计算机网络课程设计.zip

    基于P2P的局域网即时通信系统+项目说明(c#源码)计算机网络课程设计.zip 基于P2P的局域网即时通信系统+项目说明(c#源码)计算机网络课程设计.zip 基于P2P的局域网即时通信系统+项目说明(c#源码)计算机网络课程设计.zip...

    C#网络应用高级编程

    1.3.1 Socket类  1.3.2 面向连接的套接字  1.3.3 无连接的套接字  1.4 网络流  习题  第2章 TCP应用编程  2.1 同步TCP应用编程  2.1.1 使用套接字发送和接收数据  2.1.2 使用NetworkStream...

    C#学习文档实例讲解

    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对象...

    c#基础实例

    实例6 在SQL Server中存储显示图片 实例7 在ACESS 2000中存储显示图片 第六章 网络应用 实例1 Socket建立服务器程序 实例2 Socket建立客户端程序 实例3 P2P技术实现点对点聊天 实例4 C/S...

Global site tag (gtag.js) - Google Analytics