点对点即PeerToPeer通常简写为PP所谓网络中的点对点其实可以看成是一种对等的网络模型PP其实是实现网络上不同计算机之间不经过中继设备直接交换数据或服务的一种技术PP由于允许网络中任一台计算机可以直接连接到网络中其他计算机并与之进行数据交换这样既消除了中间环节也使得网络上的沟通变得更容易更直接
PP作为一种网络的模型它有别于传统的客户/服务器模型客户/服务器模型一般都有预定义的客户机和服务器而在PP模型转并没有明确的客户端和服务器但其实在PP模型中每一台计算机既可以看成是服务器也可以看成是客户机在网络中传统上的客户机/服务器通讯模型中发送服务请求或者发送数据的计算机一般称为客户机而接收处理服务或接收数据的计算机称为服务器而在PP网络模型中计算机不仅接收数据还有发送数据不仅提出服务请求还有接收对方的服务请求
在下面介绍的用Visual C#实现的局域网点对点通讯程序就有如下特点在网络利用此通讯程序进行通讯的任一计算机在通讯之前都需要侦听端口号接受其他机器的连接申请并在连接建立后就可以接收对方发送来的数据同时也可以向其他机器提出连接申请并在对方计算机允许建立连接请求后发送数据到对方可见在网络中利用此软件进行PP网络通讯的任一计算机既是客户机同样也是服务器
一.程序的设计调试运行的软件环境
()微软公司视窗服务器版
()Visual Studio Net正式版Net FrameWork SDK版本号
二.关键步骤及其解决方法
关键步骤就是实现信息在网络中的发送和接收数据接收使用的是Socket数据发送使用的是NetworkStream
利用Socket来接收信息
为了更清楚的说明问题程序在处理数据发送和接收时采用了不通的端口号发送数据程序在缺省状态设定的端口号为下面代码是侦听端口号接受网络中对此端口号的连接请求并在建立连接后通过Socket接收远程计算机发送来的数据
try
{
TcpListener tlListen = new TcpListener ( ) ;
//侦听端口号
tlListenStart ( ) ;
Socket skSocket = tlListenAcceptSocket ( );
//接受远程计算机的连接请求并获得用以接收数据的Socket实例
EndPoint tempRemoteEP = skSocketRemoteEndPoint;
//获得远程计算机对应的网络远程终结点
while (true)
{
Byte [] byStream = new Byte[];
//定义从远程计算机接收到数据存放的数据缓沖区
int i = skSocketReceiveFrom(byStreamref tempRemoteEP);
//接收数据并存放到定义的缓沖区中
string sMessage = SystemTextEncodingUTFGetString(byStream);
//以指定的编码从缓沖区中解析出内容
MessageBoxShow ( sMessage );
//显示传送来的数据
}
}
catch ( SystemSecuritySecurityException )
{
MessageBoxShow ( 防火墙安全错误!错误
MessageBoxButtonsOK MessageBoxIconExclamation);
}
利用NetworkStream来传送信息
在使用StreamWriter处理NetworkStream传送数据时数据传送的编码类型是UTF下列代码是对IP地址为的计算机的端口号提出连接申请并在连接申请建立后以UTF编码发送字符串您好见到您很高兴到对方由于下列代码中的注释比较详细这里就不具体介绍了下列代码也是使用NetworkStream传送数据的典型代码
try
{
TcpClient tcpc = new TcpClient ();
//对IP地址为的计算机的端口提出连接申请
NetworkStream tcpStream = tcpcGetStream ( );
//如果连接申请建立则获得用以传送数据的数据流
}
catch ( Exception )
{
MessageBoxShow ( 目标计算机拒绝连接请求! ) ;
break ;
}
try
{
string sMsg = 您好见到您很高兴 ;
StreamWriter reqStreamW = new StreamWriter (tcpStream);
//以特定的编码往向数据流中写入数据 默认为UTF编码
reqStreamWWrite (sMsg);
//将字符串写入数据流中
reqStreamWFlush ( );
//清理当前编写器的所有缓沖区并使所有缓沖数据写入基础流
}
catch(Exception)
{
MessageBoxShow (无法发送信息到目标计算机!) ;
}
当然在具体用Visual C#实现网络点对点通讯程序时还必须掌握很多其他方面的知识如资源的回收在用Visual C#编写网络应用程序的时候很多朋友遇到这样的情况当程序退出后通过Windows的资源管理器看到的是进程数目并没有减少这是因为程序中使用的线程可能并没有有效退出虽然Thread类中提供了Abort方法用以中止进程但并不能够保证成功退出因为进程中使用的某些资源并没有回收在某些情况下垃圾回收器也不能保证完全的回收资源还是需要我们自己手动回收资源的在本文介绍的程序中也涉及到资源手动回收的问题实现方法可参阅下面具体实现步骤中的第十二步
三.具体步骤
在了解掌握了上面的关键问题及其解决方法后再实现用Visual C#实现网络点对点通讯程序相对就容易许多下面是具体的实现步骤
启动Visual Studio Net并新建一个Visual C#项目名称为【Visual C#实现网络点对点通讯程序】
在Visual Studio Net集成开发环境中的【解决方案资源管理器】窗口中双击Formcs文件进入Formcs文件的编辑界面
在Formcs文件的开头用下列导入命名空间代码替代系统缺省的导入命名空间代码
using System ;
using SystemDrawing ;
using SystemCollections ;
using SystemComponentModel ;
using SystemWindowsForms ;
using SystemData ;
using SystemNetSockets ;
using SystemNet ;
using SystemIO ;
using SystemText ;
using SystemThreading ;
再把Visual StudioNet的当前窗口切换到【Formcs(设计)】窗口并从【工具箱】中的【Windows窗体组件】选项卡中往窗体中拖入下列组件
四个Button组件二个ListBox组件四个TextBox组件一个StatusBar组件五个Label组件并在四个Button组件拖入窗体后分别在窗体设计界面中双击它们则系统会在Formcs文件中分别产生这四个组件的Click事件对应的处理代码
在【解决方案资源管理器】窗口中双击Formcs文件进入Formcs文件的编辑界面以下面代码替代系统产生的InitializeComponent过程下面代码是对上面添加的组件进行初始化
private void InitializeComponent ( )
{
thislistBox = new SystemWindowsFormsListBox ( ) ;
thistextBox = new SystemWindowsFormsTextBox ( ) ;
thislabel = new SystemWindowsFormsLabel ( ) ;
thislabel = new SystemWindowsFormsLabel ( ) ;
thistextBox = new SystemWindowsFormsTextBox ( ) ;
thisbutton = new SystemWindowsFormsButton ( ) ;
thistextBox = new SystemWindowsFormsTextBox ( ) ;
thislabel = new SystemWindowsFormsLabel ( ) ;
thislabel = new SystemWindowsFormsLabel ( ) ;
thislabel = new SystemWindowsFormsLabel ( ) ;
thisbutton = new SystemWindowsFormsButton ( ) ;
thisbutton = new SystemWindowsFormsButton ( ) ;
thisbutton = new SystemWindowsFormsButton ( ) ;
thistextBox = new SystemWindowsFormsTextBox ( ) ;
thisstatusBar = new SystemWindowsFormsStatusBar ( ) ;
thisstatusBarPanel = new SystemWindowsFormsStatusBarPanel( );
thisstatusBarPanel = new SystemWindowsFormsStatusBarPanel( );
thislabel = new SystemWindowsFormsLabel ( ) ;
thislistBox = new SystemWindowsFormsListBox ( ) ;
( ( SystemComponentModelISupportInitialize )
( thisstatusBarPanel ) )BeginInit ( ) ;
( ( SystemComponentModelISupportInitialize )
( thisstatusBarPanel ) )BeginInit ( ) ;
thisSuspendLayout ( ) ;
thislistBoxItemHeight = ;
thislistBoxLocation = new SystemDrawingPoint ( ) ;
thislistBoxName = listBox ;
thislistBoxSize = new SystemDrawingSize ( ) ;
thislistBoxTabIndex = ;
thistextBoxLocation = new SystemDrawingPoint ( ) ;
thistextBoxName = textBox ;
thistextBoxSize = new SystemDrawingSize ( ) ;
thistextBoxTabIndex = ;
thistextBoxText = ;
thislabelLocation = new SystemDrawingPoint ( ) ;
thislabelNa