根據以上總結的客戶端與服務器端的通信過程,
我們先來寫一個服務器端。
private void btnOpen_Click(object sender, EventArgs e)
{
//創建一個Socket對象
Socket severSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//綁定端口和IP
IPEndPoint endPoint=new IPEndPoint(IPAddress.Parse(txtIP.Text),int.Parse(txtPort.Text));
severSocket.Bind(endPoint);
//開始監聽
severSocket.Listen(10);
//開始連接
//主線程會在這裏一直阻塞,直到連接到一個客戶端
//返回值是一個代理通信Socket對象
Socket socket = severSocket.Accept();
txtLog.Text = "已成功連接:"+socket.RemoteEndPoint+"\r\n" + this.txtLog.Text;
//發送消息
byte[] myBuffer=Encoding.Default.GetBytes(DateTime.Now.ToString());
socket.Send(myBuffer);
txtLog.Text = "消息已成功發送\r\n" + this.txtLog.Text;
//關閉代理Socket
socket.Shutdown(SocketShutdown.Both);
socket.Close();
//關閉總的Socket
txtLog.Text = "連接已斷開\r\n" + this.txtLog.Text;
severSocket.Close();
}
這裏只要根據圖上的步驟一步一步來基本沒什麼大問題。
只需要注意兩點:
(1)Socket對象的Accept方法會阻塞線程,如果在主線程執行會出現卡死的現象,直到你連接到客戶端。
(2)關於txtLog.Text的寫法,可能有人會有疑問,其實是很簡單的一個道理,
將最新的消息顯示在頭上,如果顯示數據很多的話,優勢就很明顯了,不必總是往下滾滾動條。
顯示效果如下:
這裏可以使用多線程方法來解決剛纔卡死的問題
創建一個新的線程來執行阻塞等待Accept方法
代碼如下:
private void btnOpen_Click(object sender, EventArgs e)
{
//創建一個Socket對象
Socket severSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//綁定端口和IP
IPEndPoint endPoint=new IPEndPoint(IPAddress.Parse(txtIP.Text),int.Parse(txtPort.Text));
severSocket.Bind(endPoint);
//開始監聽
severSocket.Listen(10);
//用別的線程來連接客戶端
ThreadPool.QueueUserWorkItem(new WaitCallback(CallBackSocket),severSocket);
}
public void CallBackSocket(object obj)
{
//將參數obj強轉成Socket類型
Socket severSocket = (Socket)obj;
//開始連接
//主線程會在這裏一直阻塞,直到連接到一個客戶端
//返回值是一個代理通信Socket對象
//可能連接多個客戶端,需要循環
while (true)
{
Socket socket = severSocket.Accept();
txtLog.Text = "已成功連接:" + socket.RemoteEndPoint + "\r\n" + this.txtLog.Text;
//發送消息
byte[] myBuffer = Encoding.Default.GetBytes(DateTime.Now.ToString());
socket.Send(myBuffer);
txtLog.Text = "消息已成功發送\r\n" + this.txtLog.Text;
//關閉代理Socket
socket.Shutdown(SocketShutdown.Both);
socket.Close();
//關閉總的Socket
txtLog.Text = "連接已斷開\r\n" + this.txtLog.Text;
//severSocket.Close();
}
}
如果出現跨線程訪問控件的錯誤,請查看之前的多線程學習博客裏的解決方案