}
this.listView1.Items.Add(item);
CSERVER是一个用于开启监听P2P信息的方法,客户端在登录成功以后就会立刻开启监听器,才能够实现与其它客户端的聊天:
th = new Thread(new ThreadStart(CServer));//新建一个用于监听其它客户端信息的线程 th.Start();//打开新线程 MessageBox.Show(bumessage.Accounts+\登录成功!\ this.Button1.Enabled=false; this.Button3.Enabled=false; } else if (bumessage.Info==2) { MessageBox.Show(\服务器未知错误\ } else {MessageBox.Show(bumessage.Info.ToString());} } #endregion } #endregion
图7 登录成功后的客户端界面
客户端之间的聊天同样使用了序列化的XML文档,用户在登录成功后就会启动一个新的监听器去监听其它客户端传入的聊天信息并且进行判断再将其它用户的聊天信息显示在界面上。这里也不再阐述代码。
第 22 页 共 28 页
4.4.2 采用异步套接字的文件传输
文件传输是通过一个类库实现的。由于文件传输的代码实现复杂,通过类库可以大量的简化代码,使主程序简洁易懂。类库Infinity.Networking包括了ClientBase.cs,ClientInfo.cs,Delegates.cs,INPClient.cs,INPServer.cs送的函数;ServerBase.cs和INPServer.cs则是反之亦然。核心代码如下:
ClientBase.cs:这个类实现了套接字的开启和数据的传输
using System;
using System.Net;
using System.Net.Sockets;
namespace Infinity.Networking {
///
/// ClientBase摘要. ///
public class ClientBase { private const int BUFFERSIZE = 4*1024; private int _port; private string _serverIP; private Socket _mainSoc; private ClientInfo _info; private AsyncCallback _dataRecievedCallback;//异步回调方法
public event NetworkEventHandler DataRecieved;//定义一
个事件:接收到数据时引发事件
public ClientBase(string serverIP,int port) { _serverIP = serverIP; _port = 11000; _mainSoc = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _info = new ClientInfo( _mainSoc,
new byte[BUFFERSIZE]);//ClientInfo包含了建立的套接
字和套接字读取的BYTE大小
_dataRecievedCallback = new
AsyncCallback(OnDataRecieved);//异步回调
}
// 可重写为其它超类实现更强大的功能,例如断点续传
public virtual void OnDataRecieved(byte[] data) {
,
ClientBase.cs定义了基础的文件发送函数,INPClient.cs则仅包含初始化文件发
第 23 页 共 28 页
} }
if (DataRecieved != null) { DataRecieved(this, new NetworkEventArgs(_info)); } }
public void Send(byte[] data) { _mainSoc.Send(data);//发送数据 }
public void Connect()//建立与远程主机的连接 { _mainSoc.Connect( new IPEndPoint( IPAddress.Parse(_serverIP), _port)); }
public void Disconnect()//关闭连接 { if (_mainSoc.Connected) _mainSoc.Shutdown(SocketShutdown.Both); }
public void WaitForData() { // 异步接收数据 _mainSoc.BeginReceive(_info.Buffer,0,_info.Buffer.Length, SocketFlags.None, _dataRecievedCallback,null); }
private void OnDataRecieved(IAsyncResult ar) { // 垃圾回收 GC.Collect(); int byteCount = 0; byteCount = _mainSoc.EndReceive(ar); if (byteCount == 0) { // 服务器断开连接. } else { OnDataRecieved(_info.Buffer);//接收到了数据 WaitForData(); } }
第 24 页 共 28 页
INPClient.cs 派生类INPClinet:
using System; using System.IO;
namespace Infinity.Networking {
///
/// INPClient的摘要. ///
public class INPClient : ClientBase { public INPClient(string serverIP,int port) : base(serverIP,port) {}
public void SendFile(string fileName)//发送文件类,开启一个文件流,将文件流依次读入,再使用CLIENTBASE类中的数据发送方法进行发送
{
FileStream fs = new FileStream( fileName,FileMode.Open);//根据传入的参数打开文件
byte[] im = new byte[fs.Length];//根据文件长度定义一个BYTE
fs.Read(im,0,im.Length);//将文件流中读取字节块写入相应缓冲区
base.Send(im);//使用基类(CLIENTBASE)的数据发送方法进行文件传送
} } }
INPSERVER和SERVERBASE与INPCLIENT和CLIENTBASE类似,所以这里不再详述。
结 论
即时通信是是网络发展的必然趋势,它的技术仍然在不断的改进和蓬勃发展中。本次设计虽然实现了简单的即时通信功能,但是从很多方面来说都是不完善的:实现了字符聊天却没有实现多媒体即时通信;实现了同步套接字聊天和异步套接字传送文件却没有实现更科学的异步套接字聊天和同步套接字传送文件。
在本次设计中,我深刻体会到SOCKET编程的基础性,多样化。由于与网络紧密联系,SOCKET编程的也可能出现各种未知的问题,需要我们更深入地了解网络协议和架构,才可能做出通用性高,稳定性高的即时通信程序。
第 25 页 共 28 页
参考文献
[1] Tobin. Titus, Fabio Claudio Ferracchiati. C#线程参考手册[M].王敏译.北京:清华大学出版社,2003。
[2] 黄承安,谢东文,许聪. C#网络应用案例导航[M].北京:中国铁道出版社,2003。
[3] Andrew Krowczyk, vinod Kumar. .NET网络高级编程[M].北京:清华大学出版社,2003。 [4] 周存杰. Visual C# .NET网络核心编程[M].北京:清华大学出版社,2002。 [5] 方睿,吴四九,刁仁宏. 网络数据库原理及应用[M].四川:四川大学出版社,2005。 [6] 李文志,申剑,卢方国,柳正青,王宏,陈建伟. 在.NET框架下开发一个即时通信系统[J].现代计算机.2004(2):68-72。
[7] 王跃. INTERNET上大规模用户即时通信方法研究[D].北京:北京工业大学[硕士论文],2004。
第 26 页 共 28 页
致 谢
本文是在**老师的热情关心和指导下完成的,她渊博的知识和严谨的治学作风使我受益匪浅,对顺利完成本课题起到了极大的作用。在此向他表示我最衷心的感谢!
在论文完成过程中,本人还得到了其他老师和毛磊同学的热心帮助,本人向他们表示深深的谢意!
最后向在百忙之中评审本文的各位专家、老师表示衷心的感谢!
第 27 页 共 28 页
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库基于TCP协议的简单即时通信软件的设计与实现(6)在线全文阅读。
相关推荐: