本文實現一個簡單的多線程客戶/服務器即時通訊應用程序,它將使用TCP連接。允許客戶之間及客戶 和服務器之間,個人消息與會議通信。最終目標是實現象雅虎/msn這樣的即時通訊工具。
[庫]
我創建一個ChatLibrary,它包含命令及可以著色的消息。public enum Command
{
Login = 0,
PersonalMessage = 1,
ClientList = 2,
Conference = 3,
Logout = 4
};
public class Message
{
string strSender;
string strReceiver;
Command cmdMessageCommand;
string strMessageDetail;
public Message ()
{
}
public Message (byte [] rawMessage)
{
string strRawStringMessage = System.Text.Encoding.ASCII.GetString (rawMessage);
string [] strRawStringMessageArray = strRawStringMessage.Split(new char []{'|'});
this.strSender = strRawStringMessageArray[1];
this.strReceiver = strRawStringMessageArray[2];
this.cmdMessageCommand = (Command) Convert.ToInt32(strRawStringMessageArray[3]);
this.MessageDetail = strRawStringMessageArray[4];
}
...
public byte [] GetRawMessage ()
{
System.Text.StringBuilder sbMessage = new System.Text.StringBuilder ("John");
sbMessage.Append("|");
sbMessage.Append(strSender);
sbMessage.Append("|");
sbMessage.Append(strReceiver);
sbMessage.Append("|");
sbMessage.Append((int)cmdMessageCommand);
sbMessage.Append("|");
sbMessage.Append(strMessageDetail);
sbMessage.Append("|");
return System.Text.Encoding.ASCII.GetBytes(sbMessage.ToString());
}
...
服務器
我創建了一個SocketServer 類,它調用TCPListener.Start() 方法:
IPEndPoint endPoint = new IPEndPoint (ipaAddress, iPort);
listener = new TcpListener (endPoint);
listener.Start();
然後,給監聽創建一個線程:
thrListenForClients = new Thread(new ThreadStart(ListenForClients));
thrListenForClients.Start();
ListenForClients 方法會等待連接,並賦值給一個新的Client 實例:
Client acceptClient = new Client();
acceptClient.Socket = listener.AcceptTcpClient();
listenForMessageDelegate = new ListenForMessageDelegate (ListenForMessages);
listenForMessageDelegate.BeginInvoke(acceptClient, new AsyncCallback (ListenForMessagesCallback), "Completed");
Client是一個包含TCPClient的一個類,用於連接:
public class Client {
string strName;
TcpClient tcpClient;
public Client()
{
}
public string Name
{
get{return strName;}
set{ this.strName = value;}
}
public TcpClient Socket
{
get{return tcpClient;}
set{ this.tcpClient = value;}
}
public void SendMessage (Message sendMessage)
{
NetworkStream stream = tcpClient.GetStream();
stream.Write(sendMessage.GetRawMessage() , 0, sendMessage.GetRawMessage().Length);
}
}
接下來,再用NetworkStream 讀消息:
一旦我們收到消息後,我們就可以做任何想做的了:
txtStatus.Text += "\r\n" + strDisplayMessageType + strWriteText.TrimStart(new char []{'\r','\n'});
我的SocketServer 類使用一些事件,這樣使得coding變得更容易:
public event ClientConnectedEventHandler ClientConnected;
public event ClientDisconnectingEventHandler ClientDisconnecting;
public event MessageReceivedEventHandler MessageReceived;
[客戶端]
客戶端基本上與上面一樣,創建一個包含TCPListener 的ClientSocket ,然後調用其Connect() 方法 :
IPEndPoint serverEndpoint = new IPEndPoint (ipaAddress , iPort);
tcpClient = new TcpClient ();
tcpClient.Connect(serverEndpoint);
thrListenForMessages = new Thread (new ThreadStart(ListenForMessages));
thrListenForMessages.Start();
ListenForMessages 會循環NetworkStream.Read()
然後,我們做一些處理,把得來的數據發送一個Message:
另外,我的目標是創建一個象YM/MSN 一樣的即時通訊軟件,所以,我做了兩個UI form: MessengerForm 和ClientWindow。MessengerForm 包含ClientSocket ,並接收消息。根據接收到的消息 ,調用MessengerWindow 顯示文字。
提示:文章中通過Invoke調用界面:
this.Invoke(createNewClientDelegate, new object []{receivedMessage});