今天做了一個簡易的socketIM的小示例。基本思想是開啟兩個winform,每個winform既充當服務器也充當客戶端。一個監聽8000端口,另外一個監聽8001端口,兩個winform接收到信息之后將信息顯示在form的控件上。
這篇記錄一下碼code中學到的一些東西。
1 System.Net.Sockets的使用
.net的socket庫已經將C中對socket的所有使用封裝起來了。慶幸的是基本的函數和流程還是一樣的。
想要創建socket server,步驟如下:
實例化一個socket
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
綁定端口
socket.Bind(endpoint);
監聽端口
socket.Listen(5);
Accept請求
Socket clientSocket = socket.Accept();
接收請求內容
clientSocket.Receive(byteMessage);
關閉socket
socket.Close();
創建client端,步驟如下:
實例化一個socket:
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
連接到接收端
socket.Connect(endpoint);
發送請求
socket.Send(byteMessage);
關閉socket
socket.Close();
2 多線程操作
C#中的多線程操作函數是封裝在System.Threading中。我這里是使用最簡單的多線程處理函數:
建立一個線程處理函數,這個函數是回調用的
private void BeginListen()
實例化一個Thread,並注冊回調函數
Thread thread = new Thread(new ThreadStart(BeginListen));
將線程設置為后台運行
thread.IsBackground = true;
啟動線程
thread.Start();
3 子線程處理父線程創建的winform控件
.net中winform控件只能由創建控件的線程來操作,子線程如果要操作就需要通過代理的方式來迂回。
首先是Control.InvokeRequired 屬性
如果當前線程對該控件沒有控制權限,則這個線程調用控件的InvokeRequired返回true,說明這個線程只有調用Invoke方法才能修改控件的屬性
如果當前線程對該控件有控制權限,則這個屬性返回false
其次是Control.Invoke方法
這個方法有兩個參數,第一個是方法,第二個參數是方法的參數
這個msdn上有個非常詳細的使用例子:
http://msdn.microsoft.com/zh-cn/library/a1hetckb%28v=vs.80%29.aspx
使用這兩個就可以使用這么個方法:
delegate void SetListBox(string strValue); //定義委托 private void SetListBoxValue(string value) { if (this.listBox1.InvokeRequired) { SetListBox sbox = new SetListBox(SetListBoxValue); listBox1.Invoke(sbox, value); } else { listBox1.Items.Add(value); } }
處理完這三個知識點,基本就完成了。
源碼上傳在這里:https://github.com/jianfengye/MyWorks/tree/master/SocketIM