前幾天開始學Socket編程,跟着老師一點一點的做。最后做了一個WinForm版的小聊天室。這個聊天室的客戶端和服務端都只是在本機上運行。
這里我首先和大家談談我對聊天室的一點理解,聊天室其實是服務端分配一個端口,開啟一個一直監聽有沒有客戶端來連接服務器的Socket,
如果一台客戶端要去連接這台服務器,那么就會分配一個通信用的Socket並知道這台服務器的IP和端口號,去向服務器發出連接請求,
如果服務器的監聽Socket監聽到有一台客戶端發出連接請求,那么服務器監聽Socket就會創建一個新的Socket,也稱連接Socket來和
客戶端進行連接通信。
下面上服務端開始監聽Socket的代碼:
//監聽Socket private void btnStart_Click(object sender, EventArgs e) { //ip地址 IPAddress ip = IPAddress.Parse(txtServer.Text); //IP地址和端口號 IPEndPoint point = new IPEndPoint(ip, int.Parse(txtPort.Text)); //創建監聽Socket Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //綁定IP和端口號 socket.Bind(point); ////通常每個套接字地址(協議/網絡地址/端口)只允許使用一次。 ////開啟監聽Socket 監聽隊列的長度 socket.Listen(10); btnStart.Enabled = false; ShowMsg("開始監聽..."); //監聽端口號,如果有客戶端連接,創建新的Socket用於通信 //Socket connSocket = socket.Accept(); Thread t = new Thread(Listen); t.IsBackground = true; t.Start(socket); }
服務端監聽客戶端連接請求代碼:
Socket socket = obj as Socket; //這樣可以不斷的監聽客戶端發送的連接請求 while (true){ //通常每個套接字地址(協議/網絡地址/端口)只允許使用一次。 //監聽端口號,如果有客戶端連接,創建新的Socket用於通信 //socket.Accept();會阻塞窗體的運行 Socket connSocket = socket.Accept(); //當前連接的客戶端IP和端口號 string ipport=connSocket.RemoteEndPoint.ToString(); //連接的客戶端IP和端口號顯示在下拉框中 cmbClient.Items.Add(ipport); //將連接的客戶端IP、端口號和Socket存儲Dictionary中 dic.Add(ipport, connSocket); //本機IP和端口號 //connSocket.LocalEndPoint ShowMsg(connSocket.RemoteEndPoint.ToString()); Thread t = new Thread(ReceiveMsg); t.IsBackground = true; t.Start(connSocket); }
客戶端Socket代碼:
//客戶端連接服務器的IP IPAddress ip = IPAddress.Parse(txtServer.Text); //客戶端連接服務器的IP和端口號 IPEndPoint point = new IPEndPoint(ip, int.Parse(txtPort.Text)); try { //創建通信連接的Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(point); ShowMsg("連接成功"); } catch(Exception ex) { ShowMsg(ex.Message); } //接收消息 Thread t = new Thread(Receive); t.IsBackground = true; t.Start();
由於代碼比較多,這里就不一一貼上所有代碼