教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

Java培訓(xùn)實(shí)戰(zhàn)教程之論Socket的重要性

更新時(shí)間:2016年01月19日14時(shí)37分 來源:傳智播客Java培訓(xùn)學(xué)院 瀏覽次數(shù):

Java培訓(xùn)中 精點(diǎn)、難點(diǎn)知識(shí)總結(jié)匯總
Socket不僅在聊天應(yīng)用程序中需要用到,而且對(duì)于學(xué)習(xí)Asp.net也非常有幫助。你懂得!
實(shí)現(xiàn)服務(wù)端和客戶端互發(fā)信息,以及服務(wù)端向多個(gè)客戶端發(fā)送信息。
     服務(wù)端代碼1:
  1.         public Form1()
  2.         {
  3.             InitializeComponent();
  4.             Control.CheckForIllegalCrossThreadCalls = false;
  5.         }
  6.         //創(chuàng)建監(jiān)聽用的socket
  7.         private void btnStartMonitor_Click(object sender, EventArgs e)
  8.         {
  9.             //監(jiān)聽的ip地址
  10.             IPAddress ip = IPAddress.Parse(txtIP.Text);
  11.             //監(jiān)聽的ip地址和端口號(hào)
  12.             IPEndPoint point = new IPEndPoint(ip, int.Parse(txtPortNumber.Text));
  13.             //監(jiān)聽用的socket
  14.             Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  15.             //通常每個(gè)套接字地址(協(xié)議/網(wǎng)絡(luò)地址/端口)只允許使用一次
  16.             //綁定監(jiān)聽的ip地址和端口號(hào)
  17.             socket.Bind(point);
  18.             //監(jiān)聽端口   監(jiān)聽隊(duì)列的長(zhǎng)度:同一個(gè)時(shí)間等待的個(gè)數(shù)。
  19.             socket.Listen(10);
  20.             //點(diǎn)擊之后,禁用掉按鈕
  21.             btnStartMonitor.Enabled = false;
  22.             //提示用戶程序開始運(yùn)行了
  23.             ShowMsg("開始運(yùn)行了...");
  24.             //監(jiān)聽端口,如果有客戶端連接,創(chuàng)建通信用socket
  25.             //阻塞窗體的運(yùn)行
  26.             //Socket connSocket = socket.Accept();
  27.             //用線程來解決窗體假死的問題
  28.             Thread th = new Thread(Listen);
  29.             th.IsBackground = true;//后臺(tái)線程
  30.             th.Start(socket);
  31.         }
  32.         //監(jiān)聽是否有客戶端連接
  33.         void Listen(object o)
  34.         {
  35.             //監(jiān)聽用的socket
  36.             Socket socket = o as Socket;
  37.             //監(jiān)聽端口
  38.             Socket connSocket = socket.Accept();
  39.             //顯示遠(yuǎn)程連接的IP地址和端口號(hào)
  40.             ShowMsg(connSocket.RemoteEndPoint.ToString());
  41.         }
  42.         //在文本框顯示信息
  43.         void ShowMsg(string msg)
  44.         {
  45.             txtShowMessage.AppendText(msg + "\r\n");
  46.         }
復(fù)制代碼
以上代碼只能讓一個(gè)客戶端連接服務(wù)端,弊端。
     服務(wù)端代碼2完善——循環(huán)接收客戶端連接:
  1.         //監(jiān)聽是否有客戶端連接
  2.        void Listen(object o)
  3.         {
  4.             //監(jiān)聽用的socket
  5.             Socket socket = o as Socket;
  6.             //可以不停地接受客戶端的連接
  7.             while (true)
  8.             {
  9.                 //負(fù)責(zé)通信用的socket
  10.                 Socket connSocket = socket.Accept();
  11.                 //顯示遠(yuǎn)程連接的IP地址和端口號(hào)
  12.                 ShowMsg(connSocket.RemoteEndPoint.ToString());
  13.                 //本機(jī)的IP地址和端口號(hào)
  14.                 //connSocket.LocalEndPoint
  15.                 //接收數(shù)據(jù)
  16.                 byte[] buffer = new byte[1024 * 1023];
  17.                 //接收數(shù)據(jù),把數(shù)據(jù)發(fā)到buffer中
  18.                 //num是實(shí)際接收到的字節(jié)個(gè)數(shù)
  19.                 int num=connSocket.Receive(buffer);
  20.                 //把實(shí)際有效的字節(jié)轉(zhuǎn)換成字符串
  21.                 string str = Encoding.UTF8.GetString(buffer, 0, num);
  22.                 ShowMsg(str);
  23.             }
  24.         }
復(fù)制代碼
服務(wù)端代碼3完善——循環(huán)接收消息:
  1.         //監(jiān)聽是否有客戶端連接
  2.         void Listen(object o)
  3.         {
  4.             //監(jiān)聽用的socket
  5.             Socket socket = o as Socket;
  6.             //可以不停地接受客戶端的連接
  7.             while (true)
  8.             {
  9.                 //負(fù)責(zé)通信用的socket
  10.                 Socket connSocket = socket.Accept();
  11.                 //顯示遠(yuǎn)程連接的IP地址和端口號(hào)
  12.                 ShowMsg(connSocket.RemoteEndPoint.ToString());
  13.                 //本機(jī)的IP地址和端口號(hào)
  14.                 //connSocket.LocalEndPoint
  15. //循環(huán)接收消息
  16. while(true)
  17. {
  18.                 //接收數(shù)據(jù)
  19.                 byte[] buffer = new byte[1024 * 1023];
  20.                 //接收數(shù)據(jù),把數(shù)據(jù)發(fā)到buffer中
  21.                 //num是實(shí)際接收到的字節(jié)個(gè)數(shù)
  22.                 int num=connSocket.Receive(buffer);
  23.                 //把實(shí)際有效的字節(jié)轉(zhuǎn)換成字符串
  24.                 string str = Encoding.UTF8.GetString(buffer, 0, num);
  25.                 ShowMsg(str);
  26. }
  27.             }
  28.         }
復(fù)制代碼
服務(wù)端代碼4完善——循環(huán)多個(gè)客戶端并接收信息:
  1.         //監(jiān)聽是否有客戶端連接
  2.         void Listen(object o)
  3.         {
  4.             //監(jiān)聽用的socket
  5.             Socket socket = o as Socket;
  6.             //可以不停地接受客戶端的連接
  7.             while (true)
  8.             {
  9.                 //負(fù)責(zé)通信用的socket
  10.                 Socket connSocket = socket.Accept();
  11.                 //顯示遠(yuǎn)程連接的IP地址和端口號(hào)
  12.                 ShowMsg(connSocket.RemoteEndPoint.ToString());
  13.                 //本機(jī)的IP地址和端口號(hào)
  14.                 //connSocket.LocalEndPoint
  15.                 //線程接收信息
  16.                 Thread th = new Thread(RecMsg);
  17.                 th.IsBackground = true;
  18.                 th.Start(connSocket);            
  19. }
  20.         }
  21.         //接收信息
  22.         void RecMsg(object o)
  23.         {
  24.             //通信用的socket
  25.             Socket connSocket = o as Socket;
  26.             //可以不停地接受客戶端的內(nèi)容
  27.             while (true)
  28.             {
  29.                 //接受數(shù)據(jù)
  30.                 byte[] buffer = new byte[1024 * 1024];
  31.                 //接受數(shù)據(jù),把數(shù)據(jù)發(fā)到buffer中
  32.                 //num就是實(shí)際接受到的字節(jié)個(gè)數(shù)
  33.                 int num = connSocket.Receive(buffer);
  34. //當(dāng)telnet關(guān)閉,會(huì)不停的發(fā)送空(0)字節(jié)
  35.                 //把實(shí)際有效的字節(jié)轉(zhuǎn)化成字符串
  36.                 string str = Encoding.UTF8.GetString(buffer, 0, num);
  37.                 ShowMsg(connSocket.RemoteEndPoint.ToString() + ":" + str);
  38.                 }
  39.             }
  40.         }
復(fù)制代碼
服務(wù)端代碼5完善——限制客戶端連接數(shù):
  1.         //限制連接客戶端的個(gè)數(shù)
  2.         int count=0;
  3.         void Listen(object o)
  4.         {
  5.             //監(jiān)聽用的socket
  6.             Socket socket = o as Socket;
  7.             //可以不停地接受客戶端的連接
  8.             while (count<1000)
  9.             {
  10.                 //負(fù)責(zé)通信用的socket
  11.                 Socket connSocket = socket.Accept();
  12.                 //顯示遠(yuǎn)程連接的IP地址和端口號(hào)
  13.                 ShowMsg(connSocket.RemoteEndPoint.ToString());
  14.                 //本機(jī)的IP地址和端口號(hào)
  15.                 //connSocket.LocalEndPoint
  16.                 //線程接收信息
  17.                 Thread th = new Thread(RecMsg);
  18.                 th.IsBackground = true;
  19.                 th.Start(connSocket);
  20. }
  21.         }
復(fù)制代碼
服務(wù)端代碼6完善——解決“當(dāng)tenet關(guān)閉,會(huì)不停地發(fā)送空(0)字節(jié)”:
  1.         //接收信息
  2.         void RecMsg(object o)
  3.         {
  4.             //通信用的socket
  5.             Socket connSocket = o as Socket;
  6.             //可以不停地接受客戶端的內(nèi)容
  7.             while (true)
  8.             {
  9.                 //接受數(shù)據(jù)
  10.                 byte[] buffer = new byte[1024 * 1024];
  11.                 //接受數(shù)據(jù),把數(shù)據(jù)發(fā)到buffer中
  12.                 //num就是實(shí)際接受到的字節(jié)個(gè)數(shù)
  13.                 int num = connSocket.Receive(buffer);
  14. //當(dāng)telnet關(guān)閉,會(huì)不停的發(fā)送空(0)字節(jié)
  15.                     //當(dāng)telnet關(guān)閉,會(huì)不停的發(fā)送(0)個(gè)字節(jié)  客戶端斷開
  16.                     if (num == 0)
  17.                     {
  18.                         ShowMsg(connSocket.RemoteEndPoint.ToString() + ":退出");
  19.                         connSocket.Shutdown(SocketShutdown.Receive);
  20.                         connSocket.Close();
  21.                         break;
  22.                     }
  23.                 //把實(shí)際有效的字節(jié)轉(zhuǎn)化成字符串
  24.                 string str = Encoding.UTF8.GetString(buffer, 0, num);
  25.                 ShowMsg(connSocket.RemoteEndPoint.ToString() + ":" + str);
  26.                 }
  27.             }
  28.         }
復(fù)制代碼
客戶端代碼1:
  1.         public Form1()
  2.         {
  3.             InitializeComponent();
  4.             Control.CheckForIllegalCrossThreadCalls = false;
  5.         }
  6.         //連接服務(wù)端和發(fā)送信息都要用到同一個(gè)socket,將其定義到外邊
  7.         Socket socket;
  8.         //連接服務(wù)端
  9.         private void btnConnect_Click(object sender, EventArgs e)
  10.         {
  11.             //客戶端連接服務(wù)器的ip地址
  12.             IPAddress ip = IPAddress.Parse(txtIP.Text);
  13.             //客戶端連接的服務(wù)器的ip地址和端口號(hào)
  14.             IPEndPoint point = new IPEndPoint(ip, int.Parse(txtPortNumber.Text));
  15.             //創(chuàng)建連接使用的socket
  16. socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  17.             try
  18.             {
  19.                 //連接聊天服務(wù)器
  20.                 //服務(wù)器沒開報(bào)錯(cuò)
  21.                 //由于目標(biāo)計(jì)算機(jī)積極拒絕,無法連接。
  22.                 socket.Connect(point);
  23.                 ShowMsg("連接成功");
  24.             }
  25.             catch (Exception ex)
  26.             {
  27.                 ShowMsg(ex.Message);
  28.             }
  29.         }
  30.         void ShowMsg(string msg)
  31.         {
  32.             txtShowMessage.AppendText(msg + "\r\n");
  33.         }
  34.         //發(fā)送消息
  35.         private void btnSendMessage_Click(object sender, EventArgs e)
  36.         {
  37.             if (socket != null)
  38.             {
  39.                 byte[] buffer = Encoding.UTF8.GetBytes(txtInputMessage.Text);
  40.                 socket.Send(buffer);
  41.             }
  42.             else
  43.             {
  44.                 MessageBox.Show("請(qǐng)先連接");
  45.             }
  46.         }
復(fù)制代碼
客戶端代碼7完善——服務(wù)端知道客戶端關(guān)閉的消息:
  1.         //接收信息
  2.         void RecMsg(object o)
  3.         {
  4.             //通信用的socket
  5.             Socket connSocket = o as Socket;
  6.             //可以不停地接受客戶端的內(nèi)容
  7.             while (true)
  8.             {
  9.                 //接受數(shù)據(jù)
  10.                 byte[] buffer = new byte[1024 * 1024];
  11.                 //接受數(shù)據(jù),把數(shù)據(jù)發(fā)到buffer中
  12.                 //num就是實(shí)際接受到的字節(jié)個(gè)數(shù)
  13.                 int num = -1;
  14.                 try
  15.                 {
  16.         //遠(yuǎn)程主機(jī)強(qiáng)迫關(guān)閉了一個(gè)現(xiàn)有的連接。  當(dāng)客戶端關(guān)閉,服務(wù)端未關(guān)閉時(shí),報(bào)錯(cuò)。
  17.                     num = connSocket.Receive(buffer);
  18.                     //當(dāng)telnet關(guān)閉,會(huì)不停的發(fā)送(0)個(gè)字節(jié)  客戶端斷開
  19.                     if (num == 0)
  20.                     {
  21.                         ShowMsg(connSocket.RemoteEndPoint.ToString() + ":退出");
  22.                         connSocket.Shutdown(SocketShutdown.Receive);
  23.                         connSocket.Close();
  24.                         break;
  25.                     }
  26.                     //把實(shí)際有效的字節(jié)轉(zhuǎn)化成字符串
  27.                     string str = Encoding.UTF8.GetString(buffer, 0, num);
  28.                     ShowMsg(connSocket.RemoteEndPoint.ToString() + ":" + str);
  29.                 }
  30.                 catch (Exception ex)
  31.                 {
  32.                     ShowMsg(ex.Message);
  33.                     //出現(xiàn)異常,跳出循環(huán)
  34.                     break;
  35.                 }
  36.             }
  37.         }
復(fù)制代碼
服務(wù)端代碼8完善——服務(wù)端給客戶端發(fā)送消息:
  1.         //發(fā)送消息
  2.         private void btnSendMessage_Click(object sender, EventArgs e)
  3.         {
  4.             if (connSocket!=null)
  5.             {
  6.                 byte[] buffer = Encoding.UTF8.GetBytes(txtInputMessage.Text);
  7.                 try
  8.                 {
  9.                     connSocket.Send(buffer);
  10.                 }
  11.                 catch (Exception ex)
  12.                 {
  13.                     ShowMsg(ex.Message);
  14.                 }
  15.             }
  16.         }
復(fù)制代碼
客戶端代碼2完善——客戶端接收服務(wù)端發(fā)送的消息:
  1.         //接收消息
  2.         void RecMsg()
  3.         {
  4.             while (true)
  5.             {
  6.                 byte[] buffer = new byte[1024 * 1024];
  7.                 try
  8.                 {
  9.                     int num = socket.Receive(buffer);
  10.                     string str = Encoding.UTF8.GetString(buffer, 1, num );
  11.                     ShowMsg(str);
  12.                 }
  13.                 catch (Exception ex)
  14.                 {
  15.                     ShowMsg(ex.Message);
  16.                     break;
  17.                 }
  18.             }
  19.         }
  20. //由于接收消息是一個(gè)死循環(huán),需要用到線程
  21.                 //線程接受消息
  22.                 Thread th = new Thread(RecMsg);
  23.                 th.IsBackground = true;
  24.                 th.Start();
復(fù)制代碼
服務(wù)端代碼9完善——服務(wù)端給指定客戶端發(fā)送消息:
  1.         //存儲(chǔ)通信用的socket字典
  2.         Dictionary<string, Socket> dic = new Dictionary<string, Socket>();
  3.         //限制連接客戶端的個(gè)數(shù)
  4.         int count = 0;
  5.         //監(jiān)聽是否有客戶端連接
  6.         void Listen(object o)
  7.         {
  8.             //監(jiān)聽用的socket
  9.             Socket socket = o as Socket;
  10.             //可以不停地接受客戶端的連接
  11.             while (count < 100)
  12.             {
  13.                 count++;
  14.                 //監(jiān)聽端口,如果有客戶端連接,創(chuàng)建通信用socket
  15.                 Socket connSocket = socket.Accept();
  16.                 //顯示遠(yuǎn)程連接的IP地址和端口號(hào)
  17.                 ShowMsg(connSocket.RemoteEndPoint.ToString());
  18.                 //本機(jī)的IP地址和端口號(hào)
  19.                 //connSocket.LocalEndPoint
  20.                 //保存當(dāng)前登錄的客戶端的socket
  21.                 string ipport = connSocket.RemoteEndPoint.ToString();
  22.                 cboUser.Items.Add(ipport);
  23.                 dic.Add(ipport, connSocket);
  24.                 //線程接收信息
  25.                 Thread th = new Thread(RecMsg);
  26.                 th.IsBackground = true;
  27.                 th.Start(connSocket);
  28.             }
  29.         }
  30.         //發(fā)送消息
  31.         private void btnSendMessage_Click(object sender, EventArgs e)
  32.         {
  33.             //獲取下拉框中選擇的ip和端口號(hào)
  34.             string ipport = cboUser.Text;
  35.             if (!string.IsNullOrEmpty(ipport))
  36.             {
  37.                 byte[] buffer = Encoding.UTF8.GetBytes(txtInputMessage.Text);
  38.                 try
  39.                 {
  40.                     //根據(jù)key獲得socket
  41.                     Socket connSocket = dic[ipport];
  42.                     connSocket.Send(buffer);
  43.                 }
  44.                 catch (Exception ex)
  45.                 {
  46.                     ShowMsg(ex.Message);
  47.                 }
  48.             }
  49.             else
  50.             {
  51.                 MessageBox.Show("請(qǐng)選擇客戶端");
  52.             }
  53.         }
復(fù)制代碼
Java培訓(xùn)學(xué)院始終認(rèn)為你將會(huì)是最優(yōu)秀的存在,你就是最棒的,看好你,加油!??!
本文版權(quán)歸傳智播客Java培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:傳智播客Java培訓(xùn)學(xué)院
首發(fā):http://8y3kgpwe.cn/javaee 
0 分享到:
和我們?cè)诰€交談!