精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

C#網(wǎng)絡(luò)編程系列九:類似QQ的即時(shí)通信程序

開發(fā) 后端
為了讓大家更好的理解我們平常中常見的軟件QQ的工作原理,所以在本專題中將利用前面專題介紹的知識來實(shí)現(xiàn)一個(gè)類似QQ的聊天程序。

引言:前面專題中介紹了UDP、TCP和P2P編程,并且通過一些小的示例來讓大家更好的理解它們的工作原理以及怎樣.Net類庫去實(shí)現(xiàn)它們的。為了讓大家更好的理解我們平常中常見的軟件QQ的工作原理,所以在本專題中將利用前面專題介紹的知識來實(shí)現(xiàn)一個(gè)類似QQ的聊天程序。

一、即時(shí)通信系統(tǒng)

在我們的生活中經(jīng)常使用即時(shí)通信的軟件,我們經(jīng)常接觸到的有:QQ、阿里旺旺、MSN等等。這些都是屬于即時(shí)通信(Instant Messenger,IM)軟件,IM是指所有能夠即時(shí)發(fā)送和接收互聯(lián)網(wǎng)消息的軟件。

在前面專題P2P編程中介紹過P2P系統(tǒng)分兩種類型——單純型P2P和混合型P2P(QQ就是屬于混合型的應(yīng)用),混合型P2P系統(tǒng)中的服務(wù)器(也叫索引服務(wù)器)起到協(xié)調(diào)的作用。在文件共享類應(yīng)用中,如果采用混合型P2P技術(shù)的話,索引服務(wù)器就保存著文件信息,這樣就可能會造成版權(quán)的問題,然而在即時(shí)通信類的軟件中, 因?yàn)榭蛻舳藗鬟f的都是簡單的聊天文本而不是網(wǎng)絡(luò)媒體資源,這樣就不存在版權(quán)問題了,在這種情況下,就可以采用混合型P2P技術(shù)來實(shí)現(xiàn)我們的即時(shí)通信軟件。前面已經(jīng)講了,騰訊的QQ就是屬于混合型P2P的軟件。

因此本專題要實(shí)現(xiàn)一個(gè)類似QQ的聊天程序,其中用到的P2P技術(shù)是屬于混合型P2P,而不是前一專題中的采用的單純型P2P技術(shù),同時(shí)本程序的實(shí)現(xiàn)也會用到TCP、UDP編程技術(shù)。具體的相關(guān)內(nèi)容大家可以查看本系列的相關(guān)專題的。

二、程序?qū)崿F(xiàn)的詳細(xì)設(shè)計(jì)

本程序采用P2P方式,各個(gè)客戶端之間直接發(fā)消息進(jìn)行聊天,服務(wù)器在其中只是起到協(xié)調(diào)的作用,下面先理清下程序的流程:

2.1 程序流程設(shè)計(jì)

當(dāng)一個(gè)新用戶通過客戶端登陸系統(tǒng)后,從服務(wù)器獲取當(dāng)在線的用戶信息列表,列表信息包括系統(tǒng)中每個(gè)用戶的地址,然后用戶就可以單獨(dú)向其他發(fā)消息。如果有用戶加入或者在線用戶退出時(shí),服務(wù)器就會及時(shí)發(fā)消息通知系統(tǒng)中的所有其他客戶端,達(dá)到它們即時(shí)地更新用戶信息列表。

根據(jù)上面大致的描述,我們可以把系統(tǒng)的流程分為下面幾步來更好的理解(大家可以參考QQ程序?qū)玫睦斫獗境绦虻牧鞒蹋?/p>

1.用戶通過客戶端進(jìn)入系統(tǒng),向服務(wù)器發(fā)出消息,請求登陸

2.服務(wù)器收到請求后,向客戶端返回回應(yīng)消息,表示同意接受該用戶加入,并把自己(指的是服務(wù)器)所在監(jiān)聽的端口發(fā)送給客戶端

3.客戶端根據(jù)服務(wù)器發(fā)送過來的端口號和服務(wù)器建立連接

4.服務(wù)器通過該連接 把在線用戶的列表信息發(fā)送給新加入的客戶端。

5.客戶端獲得了在線用戶列表后就可以自己選擇在線用戶聊天。(程序中另外設(shè)計(jì)一個(gè)類似QQ的聊天窗口來進(jìn)行聊天)

6.當(dāng)用戶退出系統(tǒng)時(shí)也要及時(shí)通知服務(wù)器,服務(wù)器再把這個(gè)消息轉(zhuǎn)發(fā)給每個(gè)在線的用戶,使客戶端及時(shí)更新本地的用戶信息列表。

2.2 通信協(xié)議設(shè)計(jì)

所謂協(xié)議就是約定,即服務(wù)器和客戶端之間會話信息的內(nèi)容格式進(jìn)行約定,使雙方都可以識別,達(dá)到更好的通信。

下面就具體介紹下協(xié)議的設(shè)計(jì):

1. 客戶端和服務(wù)器之間的對話

(1)登陸過程

① 客戶端用匿名UDP的方式向服務(wù)器發(fā)出下面的信息:

     login, username, localIPEndPoint

消息內(nèi)容包括三個(gè)字段,每個(gè)字段用 “,”分割,login表示的是請求登陸;username表示用戶名;localIPEndPint表示客戶端本地地址。

② 服務(wù)器收到后以匿名UDP返回下面的回應(yīng):

Accept, port

其中Accept表示服務(wù)器接受請求,port表示服務(wù)器所在的端口號,服務(wù)器監(jiān)聽著這個(gè)端口的客戶端連接

③ 連接服務(wù)器,獲取用戶列表

客戶端從上一步獲得了端口號,然后向該端口發(fā)起TCP連接,向服務(wù)器索取在線用戶列表,服務(wù)器接受連接后將用戶列表傳輸?shù)娇蛻舳恕S脩袅斜硇畔⒏袷饺缦拢?/p>

  username1,IPEndPoint1;username2,IPEndPoint2;...;end

username1、username2表示用戶名,IPEndPoint1,IPEndPoint2表示對應(yīng)的端點(diǎn),每個(gè)用戶信息都是由"用戶名+端點(diǎn)"組成,用戶信息以“;”隔開,整個(gè)用戶列表以“end”結(jié)尾。

(2)注銷過程

用戶退出時(shí),向服務(wù)器發(fā)送如下消息:

   logout,username,localIPEndPoint

這條消息看字面意思大家都知道就是告訴服務(wù)器 username+localIPEndPoint這個(gè)用戶要退出了。

2. 服務(wù)器管理用戶

(1)新用戶加入通知

因?yàn)橄到y(tǒng)中在線的每個(gè)用戶都有一份當(dāng)前在線用戶表,因此當(dāng)有新用戶登錄時(shí),服務(wù)器不需要重復(fù)地給系統(tǒng)中的每個(gè)用戶再發(fā)送所有用戶信息,只需要將新加入用戶的信息通知其他用戶,其他用戶再更新自己的用戶列表。

服務(wù)器向系統(tǒng)中每個(gè)用戶廣播如下信息:

  login,username,remoteIPEndPoint

在這個(gè)過程中服務(wù)器只是負(fù)責(zé)將收到的"login"信息轉(zhuǎn)發(fā)出去。

(2)用戶退出

與新用戶加入一樣,服務(wù)器將用戶退出的消息進(jìn)行廣播轉(zhuǎn)發(fā):

    logout,username,remoteIPEndPoint

3. 客戶端之間聊天

用戶進(jìn)行聊天時(shí),各自的客戶端之間是以P2P方式進(jìn)行工作的,不與服務(wù)器有直接聯(lián)系,這也是P2P技術(shù)的特點(diǎn)。

聊天發(fā)送的消息格式如下:

   talk, longtime, selfUserName, message

其中,talk表明這是聊天內(nèi)容的消息;longtime是長時(shí)間格式的當(dāng)前系統(tǒng)時(shí)間;selfUserName為發(fā)送發(fā)的用戶名;message表示消息的內(nèi)容。

協(xié)議設(shè)計(jì)介紹完后,下面就進(jìn)入本程序的具體實(shí)現(xiàn)的介紹的。

注:協(xié)議是本程序的核心,也是所有軟件的核心,每個(gè)軟件產(chǎn)品的協(xié)議都是不一樣的,QQ有自己的一套協(xié)議,MSN又有另一套協(xié)議,所以使用的QQ的用戶無法和用MSN的朋友進(jìn)行聊天。

#p#

三、程序的實(shí)現(xiàn)

服務(wù)器端核心代碼:

  1. View Code   
  2.   // 啟動服務(wù)器  
  3.          // 根據(jù)博客中協(xié)議的設(shè)計(jì)部分  
  4.          // 客戶端先向服務(wù)器發(fā)送登錄請求,然后通過服務(wù)器返回的端口號  
  5.          // 再與服務(wù)器建立連接  
  6.          // 所以啟動服務(wù)按鈕事件中有兩個(gè)套接字:一個(gè)是接收客戶端信息套接字和  
  7.          // 監(jiān)聽客戶端連接套接字  
  8.          private void btnStart_Click(object sender, EventArgs e)  
  9.          {  
  10.              // 創(chuàng)建接收套接字  
  11.              serverIp = IPAddress.Parse(txbServerIP.Text);  
  12.              serverIPEndPoint = new IPEndPoint(serverIp, int.Parse(txbServerport.Text));  
  13.              receiveUdpClient = new UdpClient(serverIPEndPoint);  
  14.              // 啟動接收線程  
  15.              Thread receiveThread = new Thread(ReceiveMessage);  
  16.              receiveThread.Start();  
  17.              btnStart.Enabled = false;  
  18.              btnStop.Enabled = true;  
  19.    
  20.              // 隨機(jī)指定監(jiān)聽端口  
  21.              Random random = new Random();  
  22.              tcpPort = random.Next(port + 1, 65536);  
  23.    
  24.              // 創(chuàng)建監(jiān)聽套接字  
  25.              tcpListener = new TcpListener(serverIp, tcpPort);  
  26.              tcpListener.Start();  
  27.    
  28.              // 啟動監(jiān)聽線程  
  29.              Thread listenThread = new Thread(ListenClientConnect);  
  30.              listenThread.Start();  
  31.              AddItemToListBox(string.Format("服務(wù)器線程{0}啟動,監(jiān)聽端口{1}",serverIPEndPoint,tcpPort));  
  32.          }  
  33.    
  34.          // 接收客戶端發(fā)來的信息  
  35.          private void ReceiveMessage()  
  36.          {  
  37.              IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, 0);  
  38.              while (true)  
  39.              {  
  40.                  try 
  41.                  {  
  42.                      // 關(guān)閉receiveUdpClient時(shí)下面一行代碼會產(chǎn)生異常  
  43.                      byte[] receiveBytes = receiveUdpClient.Receive(ref remoteIPEndPoint);  
  44.                      string message = Encoding.Unicode.GetString(receiveBytes, 0, receiveBytes.Length);  
  45.    
  46.                      // 顯示消息內(nèi)容  
  47.                      AddItemToListBox(string.Format("{0}:{1}",remoteIPEndPoint,message));  
  48.    
  49.                      // 處理消息數(shù)據(jù)  
  50.                      // 根據(jù)協(xié)議的設(shè)計(jì)部分,從客戶端發(fā)送來的消息是具有一定格式的  
  51.                      // 服務(wù)器接收消息后要對消息做處理  
  52.                      string[] splitstring = message.Split(',');  
  53.                      // 解析用戶端地址  
  54.                      string[] splitsubstring = splitstring[2].Split(':');  
  55.                      IPEndPoint clientIPEndPoint = new IPEndPoint(IPAddress.Parse(splitsubstring[0]), int.Parse(splitsubstring[1]));  
  56.                      switch (splitstring[0])  
  57.                      {  
  58.                          // 如果是登錄信息,向客戶端發(fā)送應(yīng)答消息和廣播有新用戶登錄消息  
  59.                          case "login":  
  60.                              User user = new User(splitstring[1], clientIPEndPoint);  
  61.                              // 往在線的用戶列表添加新成員  
  62.                              userList.Add(user);  
  63.                              AddItemToListBox(string.Format("用戶{0}({1})加入", user.GetName(), user.GetIPEndPoint()));  
  64.                              string sendString = "Accept," + tcpPort.ToString();  
  65.                              // 向客戶端發(fā)送應(yīng)答消息  
  66.                              SendtoClient(user, sendString);  
  67.                              AddItemToListBox(string.Format("向{0}({1})發(fā)出:[{2}]", user.GetName(), user.GetIPEndPoint(), sendString));  
  68.                              for (int i = 0; i < userList.Count; i++)  
  69.                              {  
  70.                                  if (userList[i].GetName() != user.GetName())  
  71.                                  {  
  72.                                      // 給在線的其他用戶發(fā)送廣播消息  
  73.                                      // 通知有新用戶加入  
  74.                                      SendtoClient(userList[i], message);  
  75.                                  }  
  76.                              }  
  77.    
  78.                              AddItemToListBox(string.Format("廣播:[{0}]", message));  
  79.                              break;  
  80.                          case "logout":  
  81.                              for (int i = 0; i < userList.Count; i++)  
  82.                              {  
  83.                                  if (userList[i].GetName() == splitstring[1])  
  84.                                  {  
  85.                                      AddItemToListBox(string.Format("用戶{0}({1})退出",userList[i].GetName(),userList[i].GetIPEndPoint()));  
  86.                                      userList.RemoveAt(i); // 移除用戶  
  87.                                  }  
  88.                              }  
  89.                              for (int i = 0; i < userList.Count; i++)  
  90.                              {  
  91.                                  // 廣播注銷消息  
  92.                                  SendtoClient(userList[i], message);  
  93.                              }  
  94.                              AddItemToListBox(string.Format("廣播:[{0}]", message));  
  95.                              break;  
  96.                      }  
  97.                  }  
  98.                  catch 
  99.                  {  
  100.                      // 發(fā)送異常退出循環(huán)  
  101.                      break;  
  102.                  }  
  103.              }  
  104.              AddItemToListBox(string.Format("服務(wù)線程{0}終止", serverIPEndPoint));  
  105.          }  
  106.    
  107.          // 向客戶端發(fā)送消息  
  108.          private void SendtoClient(User user, string message)  
  109.          {  
  110.              // 匿名方式發(fā)送  
  111.              sendUdpClient = new UdpClient(0);  
  112.              byte[] sendBytes = Encoding.Unicode.GetBytes(message);  
  113.              IPEndPoint remoteIPEndPoint =user.GetIPEndPoint();  
  114.              sendUdpClient.Send(sendBytes,sendBytes.Length,remoteIPEndPoint);  
  115.              sendUdpClient.Close();  
  116.          }  
  117.           
  118.          // 接受客戶端的連接  
  119.          private void ListenClientConnect()  
  120.          {  
  121.              TcpClient newClient = null;  
  122.              while (true)  
  123.              {  
  124.                  try 
  125.                  {  
  126.                      newClient = tcpListener.AcceptTcpClient();  
  127.                      AddItemToListBox(string.Format("接受客戶端{(lán)0}的TCP請求",newClient.Client.RemoteEndPoint));  
  128.                  }  
  129.                  catch 
  130.                  {  
  131.                      AddItemToListBox(string.Format("監(jiān)聽線程({0}:{1})", serverIp, tcpPort));  
  132.                      break;  
  133.                  }  
  134.    
  135.                  Thread sendThread = new Thread(SendData);  
  136.                  sendThread.Start(newClient);  
  137.              }  
  138.          }  
  139.    
  140.          // 向客戶端發(fā)送在線用戶列表信息  
  141.          // 服務(wù)器通過TCP連接把在線用戶列表信息發(fā)送給客戶端  
  142.          private void SendData(object userClient)  
  143.          {  
  144.              TcpClient newUserClient = (TcpClient)userClient;  
  145.              userListstring = null;  
  146.              for (int i = 0; i < userList.Count; i++)  
  147.              {  
  148.                  userListstring += userList[i].GetName() + "," 
  149.                      + userList[i].GetIPEndPoint().ToString() + ";";  
  150.              }  
  151.    
  152.              userListstring += "end";  
  153.              networkStream = newUserClient.GetStream();  
  154.              binaryWriter = new BinaryWriter(networkStream);  
  155.              binaryWriter.Write(userListstring);  
  156.              binaryWriter.Flush();  
  157.              AddItemToListBox(string.Format("向{0}發(fā)送[{1}]", newUserClient.Client.RemoteEndPoint, userListstring));  
  158.              binaryWriter.Close();  
  159.              newUserClient.Close();  
  160.          } 

客戶端核心代碼:

  1. View Code   
  2.   // 登錄服務(wù)器  
  3.          private void btnlogin_Click(object sender, EventArgs e)  
  4.          {  
  5.              // 創(chuàng)建接受套接字  
  6.              IPAddress clientIP = IPAddress.Parse(txtLocalIP.Text);  
  7.              clientIPEndPoint = new IPEndPoint(clientIP, int.Parse(txtlocalport.Text));  
  8.              receiveUdpClient = new UdpClient(clientIPEndPoint);  
  9.              // 啟動接收線程  
  10.              Thread receiveThread = new Thread(ReceiveMessage);  
  11.              receiveThread.Start();  
  12.    
  13.              // 匿名發(fā)送  
  14.              sendUdpClient = new UdpClient(0);  
  15.              // 啟動發(fā)送線程  
  16.              Thread sendThread = new Thread(SendMessage);  
  17.              sendThread.Start(string.Format("login,{0},{1}", txtusername.Text, clientIPEndPoint));  
  18.    
  19.              btnlogin.Enabled = false;  
  20.              btnLogout.Enabled = true;  
  21.              this.Text = txtusername.Text;  
  22.          }  
  23.    
  24.          // 客戶端接受服務(wù)器回應(yīng)消息   
  25.          private void ReceiveMessage()  
  26.          {  
  27.              IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any,0);  
  28.              while (true)  
  29.              {  
  30.                  try 
  31.                  {  
  32.                      // 關(guān)閉receiveUdpClient時(shí)會產(chǎn)生異常  
  33.                      byte[] receiveBytes = receiveUdpClient.Receive(ref remoteIPEndPoint);  
  34.                      string message = Encoding.Unicode.GetString(receiveBytes,0,receiveBytes.Length);  
  35.    
  36.                      // 處理消息  
  37.                      string[] splitstring = message.Split(',');  
  38.    
  39.                      switch (splitstring[0])  
  40.                      {  
  41.                          case "Accept":  
  42.                              try 
  43.                              {  
  44.                                  tcpClient = new TcpClient();  
  45.                                  tcpClient.Connect(remoteIPEndPoint.Address, int.Parse(splitstring[1]));  
  46.                                  if (tcpClient != null)  
  47.                                  {  
  48.                                      // 表示連接成功  
  49.                                      networkStream = tcpClient.GetStream();  
  50.                                      binaryReader = new BinaryReader(networkStream);  
  51.                                  }  
  52.                              }  
  53.                              catch 
  54.                              {  
  55.                                  MessageBox.Show("連接失敗""異常");  
  56.                              }  
  57.    
  58.                              Thread getUserListThread = new Thread(GetUserList);  
  59.                              getUserListThread.Start();  
  60.                              break;  
  61.                          case "login":  
  62.                              string userItem = splitstring[1] + "," + splitstring[2];  
  63.                              AddItemToListView(userItem);  
  64.                              break;  
  65.                          case "logout":  
  66.                              RemoveItemFromListView(splitstring[1]);  
  67.                              break;  
  68.                          case "talk":  
  69.                              for (int i = 0; i < chatFormList.Count; i++)  
  70.                              {  
  71.                                  if (chatFormList[i].Text == splitstring[2])  
  72.                                  {  
  73.                                      chatFormList[i].ShowTalkInfo(splitstring[2], splitstring[1], splitstring[3]);  
  74.                                  }  
  75.                              }  
  76.    
  77.                              break;  
  78.                      }  
  79.                  }  
  80.                  catch 
  81.                  {  
  82.                      break;  
  83.                  }  
  84.              }  
  85.          }  
  86.    
  87.          // 從服務(wù)器獲取在線用戶列表  
  88.          private void GetUserList()  
  89.          {  
  90.              while (true)  
  91.              {  
  92.                  userListstring = null;  
  93.                  try 
  94.                  {  
  95.                      userListstring = binaryReader.ReadString();  
  96.                      if (userListstring.EndsWith("end"))  
  97.                      {  
  98.                          string[] splitstring = userListstring.Split(';');  
  99.                          for (int i = 0; i < splitstring.Length - 1; i++)  
  100.                          {  
  101.                              AddItemToListView(splitstring[i]);  
  102.                          }  
  103.    
  104.                          binaryReader.Close();  
  105.                          tcpClient.Close();  
  106.                          break;  
  107.                      }  
  108.                  }  
  109.                  catch 
  110.                  {  
  111.                      break;  
  112.                  }  
  113.              }  
  114.          }  
  115.     // 發(fā)送登錄請求  
  116.          private void SendMessage(object obj)  
  117.          {  
  118.              string message = (string)obj;  
  119.              byte[] sendbytes = Encoding.Unicode.GetBytes(message);  
  120.              IPAddress remoteIp = IPAddress.Parse(txtserverIP.Text);  
  121.              IPEndPoint remoteIPEndPoint = new IPEndPoint(remoteIp, int.Parse(txtServerport.Text));  
  122.              sendUdpClient.Send(sendbytes, sendbytes.Length, remoteIPEndPoint);  
  123.              sendUdpClient.Close();  
  124.          } 

程序的運(yùn)行結(jié)果:

首先先運(yùn)行服務(wù)器窗口,在服務(wù)器窗口點(diǎn)擊“啟動”按鈕來啟動服務(wù)器,然后客戶端首先指定服務(wù)器的端口號,修改用戶名(這里也可以不修改,使用默認(rèn)的也可以),然后點(diǎn)擊“登錄”按鈕來登陸服務(wù)器(也就是告訴服務(wù)器本地的客戶端地址),然后從服務(wù)器端獲得在線用戶列表,界面演示如下:

然后用戶可以雙擊在線用戶進(jìn)行聊天(此程序支持與多人進(jìn)行聊天),下面是功能的演示圖片:

雙方進(jìn)行聊天時(shí),這里沒有實(shí)現(xiàn)像QQ一樣,有人發(fā)信息來在對應(yīng)的客戶端就有消息提醒的功能的, 所以雙方進(jìn)行聊天的過程中,每個(gè)客戶端都需要在在線用戶列表中點(diǎn)擊聊天的對象來激活聊天對話框(意思就是從圖片中可以看出“天涯”客戶端想和劍癡聊天的話,就在“在線用戶”列表雙擊劍癡來激活聊天窗口,同時(shí)“劍癡”客戶端也必須雙擊“天涯”來激活聊天窗口,這樣雙方就看到對方發(fā)來的信息了,(不激活窗口,也是發(fā)送了信息,只是沒有一個(gè)窗口來進(jìn)行顯示)),而且從圖片中也可以看出——此程序支持與多人聊天,即天涯同時(shí)與“劍癡”和"大地"同時(shí)聊天。

四、總結(jié)

本專題介紹了如何去實(shí)現(xiàn)一個(gè)類似QQ的聊天程序,一方面讓大家可以鞏固前面專題的內(nèi)容,另一方面讓大家更好的理解即時(shí)通信軟件(騰訊QQ)的工作原理和軟件協(xié)議的設(shè)計(jì)。

后面一專題將介紹如何去實(shí)現(xiàn)郵件系統(tǒng)中常用的功能——實(shí)現(xiàn)一個(gè)簡單的郵件應(yīng)用。

本程序的源代碼鏈接:http://files.cnblogs.com/zhili/IM.zip 

原文鏈接:http://www.cnblogs.com/zhili/archive/2012/09/23/QQ_P2P.html

【編輯推薦】

    1. C#網(wǎng)絡(luò)編程系列一:網(wǎng)絡(luò)協(xié)議簡介
    2. C#網(wǎng)絡(luò)編程系列二:HTTP協(xié)議詳解
    3. C#網(wǎng)絡(luò)編程系列三:自定義Web服務(wù)器
    4. C#網(wǎng)絡(luò)編程系列四:自定義Web瀏覽器
    5. C#網(wǎng)絡(luò)編程系列五:TCP編程
    6. C#網(wǎng)絡(luò)編程系列六:UDP編程
    7. C#網(wǎng)絡(luò)編程系列七:UDP編程補(bǔ)充
    8. C#網(wǎng)絡(luò)編程系列八:P2P編程
    9. C#網(wǎng)絡(luò)編程系列十:實(shí)現(xiàn)簡單的郵件收發(fā)器

 

責(zé)任編輯:張偉 來源: Learning hard的博客
相關(guān)推薦

2012-09-24 15:13:50

C#網(wǎng)絡(luò)協(xié)議TCP

2012-09-24 15:35:24

C#網(wǎng)絡(luò)協(xié)議UDP

2010-04-20 09:07:13

Unix操作系統(tǒng)

2012-09-25 11:28:38

C#網(wǎng)絡(luò)協(xié)議UDP

2012-09-24 14:03:58

C#網(wǎng)絡(luò)協(xié)議C

2014-12-23 13:47:25

2015-03-09 10:33:14

即時(shí)通信管道過濾

2012-09-24 14:09:31

C#網(wǎng)絡(luò)協(xié)議C

2012-09-25 13:47:43

C#網(wǎng)絡(luò)協(xié)議P2P

2024-03-04 18:49:59

反射C#開發(fā)

2011-10-20 22:25:49

網(wǎng)易即時(shí)通

2010-05-10 17:43:07

2009-08-25 17:24:55

C#串口通信程序

2012-09-25 15:02:50

C#網(wǎng)絡(luò)協(xié)議

2023-10-30 17:48:30

架構(gòu)設(shè)計(jì)通信

2009-02-26 16:40:49

企業(yè) 通信

2009-08-24 17:20:13

C#網(wǎng)絡(luò)通信TCP連接

2016-10-11 13:58:03

2018-01-15 09:32:59

即時(shí)通信服務(wù)器架構(gòu)

2009-01-20 19:27:02

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

亚洲日本成人网| 久久精品国产亚洲aⅴ| 日本一区二区三区视频在线| 国产一区二区三区久久久| 在线看欧美日韩| 蜜桃福利午夜精品一区| 91在线三级| 福利视频网站一区二区三区| 日本久久久久久久久久久| 五月天婷婷丁香网| 国产精品videossex| 亚洲尤物视频在线| 日韩欧美精品一区二区三区经典| 丰满人妻老熟妇伦人精品| 久久国产亚洲精品| 欧美日韩色综合| 亚洲 国产 欧美一区| 中文字幕高清在线免费播放| 婷婷亚洲五月色综合| 精品亚洲一区二区三区在线播放| 国产美女视频免费看| 国产在线观看免费麻豆| 精品一区二区三区在线观看国产| 91国产中文字幕| 爱爱的免费视频| 偷拍视频一区二区三区| 亚洲精品福利视频网站| 水蜜桃亚洲精品| 五月激情六月婷婷| 天堂久久一区二区三区| 亚洲一区二区久久| 国产麻豆剧传媒精品国产av| 午夜裸体女人视频网站在线观看| 久久午夜国产精品| 成人高清在线观看| 亚洲高清毛片一区二区| 成人羞羞视频在线看网址| 亚洲精品成人久久电影| 无码精品国产一区二区三区免费| 日本色护士高潮视频在线观看| 中文字幕一区二区三中文字幕| 欧美日韩亚洲在线| 天堂国产一区二区三区| 福利一区在线观看| 国产成人免费av| 婷婷社区五月天| 大色综合视频网站在线播放| 亚洲人成亚洲人成在线观看| www.超碰97| 麻豆国产欧美一区二区三区r| 色妞www精品视频| 波多野结衣激情| 欧美精品电影| 中文字幕一区视频| 国产又粗又爽又黄的视频| 亚洲乱亚洲乱妇| 99久久99精品久久久久久| 不卡一区二区三区视频| 亚洲精品一区二区三区蜜桃| 麻豆久久婷婷| 国产精品久久久久久久一区探花| 日韩黄色片网站| 蜜臀av一区二区在线观看| 欧美成人性生活| 亚洲a v网站| 国产传媒欧美日韩成人精品大片| 亚洲人成网站在线播| 亚洲精品国产精品国自产网站| 精品欧美激情在线观看| 在线观看视频亚洲| 青青操在线视频观看| 欧美jizzhd精品欧美巨大免费| 亚洲日韩中文字幕在线播放| 又黄又色的网站| 亚洲精品毛片| 日韩欧美国产网站| 欧美日韩国产色| 久久九九亚洲综合| 日日骚一区二区三区| 欧美久久综合网| 日韩精品视频免费| 国产精品无码一区二区三区| 国产精品最新| 色系列之999| 久久午夜鲁丝片午夜精品| 国产欧美在线| 久久久视频在线| 麻豆成人免费视频| 美女免费视频一区| 国产精品国内视频| 国产精品高潮呻吟av| 久久久综合网| 68精品国产免费久久久久久婷婷| 无码人妻精品一区二区三区蜜桃91 | 亚洲欧美日本精品| 精品伦精品一区二区三区视频密桃| 欧美在线国产| 不卡av电影院| 成人无码av片在线观看| 亚洲欧美在线专区| 日韩性生活视频| 亚洲综合一二三| 麻豆国产精品一区二区三区| 国产成人久久精品| www.色视频| 麻豆91在线观看| 国产美女精品久久久| 国产理论电影在线观看| 久久精品亚洲乱码伦伦中文| 欧美与动交zoz0z| 偷拍中文亚洲欧美动漫| 精品久久久久久久人人人人传媒 | 性欧美大战久久久久久久久| 国产视频一区二区视频| 六月婷婷综合| 日韩欧美国产网站| 一级片黄色免费| 激情五月综合| 午夜精品久久久久久久99黑人 | 国产精品自在在线| 日本在线高清视频一区| 黄色成人在线网| 欧美日韩免费观看一区三区| 亚洲美女爱爱视频| 美女少妇全过程你懂的久久| 亚洲欧美国产精品va在线观看| 中文字幕国产综合| 好吊日精品视频| 91精品久久久久久久久久久久久久| 中文字幕码精品视频网站| 奇米影视一区二区三区小说| 久久久亚洲综合网站| 毛片免费在线| 欧美国产日韩a欧美在线观看| www.国产在线视频| 国产精品日本一区二区三区在线| 尤物精品国产第一福利三区 | 九色porny丨首页在线| 国产精品久久久久久久久晋中| 成人免费在线小视频| 羞羞影院欧美| 亚洲另类图片色| 手机免费观看av| 视频一区中文字幕国产| 久久综合久久综合这里只有精品| 麻豆视频在线观看免费网站黄| 精品国产乱码久久久久久久| 免费网站看av| 国产美女在线精品| 一级黄色片播放| 精品国产亚洲一区二区三区在线 | 在线观看特色大片免费视频| 精品卡一卡二卡三卡四在线| 玖玖爱免费视频| av不卡免费看| 国产亚洲自拍偷拍| 福利影院在线看| 亚洲韩国日本中文字幕| 国产成人一区二区三区影院在线| 美国十次了思思久久精品导航 | 亚洲少妇中文字幕| 成人在线电影在线观看视频| 国产成人精品电影久久久| 欧美拍拍视频| 亚洲自拍偷拍综合| 少妇一级淫免费放| 欧美gayvideo| 91在线视频成人| 精品99又大又爽又硬少妇毛片| 一区二区三区欧美日韩| 绯色av蜜臀vs少妇| 日韩精品dvd| 91po在线观看91精品国产性色| 午夜在线视频免费| 尤物视频一区二区| 中日韩av在线播放| 欧美理论在线| 成人福利视频在线观看| 性直播体位视频在线观看| 日韩美女天天操| 91看片在线播放| 国产欧美一区二区精品婷婷 | 成人h精品动漫一区二区三区| 国自产拍偷拍精品啪啪一区二区| 亚洲女娇小黑人粗硬| 欧美黑人视频一区| 四虎影视精品成人| 欧美日韩不卡在线| 国产无套内射又大又猛又粗又爽| 久久久一区二区| 毛片毛片毛片毛| 亚洲国产日韩欧美在线| 精品国产_亚洲人成在线| 图片区小说区亚洲| 日韩一二三四区| 久久久久女人精品毛片九一 | 综合久久国产| 久久天天久久| 韩国日本不卡在线| 一本一道波多野毛片中文在线| 欧美在线观看你懂的| 男人操女人的视频网站| 91丨国产丨九色丨pron| 99国产精品久久久久久| 婷婷综合五月| 蜜桃精品久久久久久久免费影院| 国产一区2区在线观看| 欧美一级免费看| 午夜羞羞小视频在线观看| 日韩欧美一二三四区| 久久久精品视频网站| 亚洲综合在线视频| 糖心vlog免费在线观看| 国产综合成人久久大片91| 一区二区三区观看| 国产一区二区三区视频在线| 不卡av在线网站| 国产在线播放av| 亚洲国产天堂久久综合| 欧美啪啪小视频| 一区二区高清在线| 26uuu成人网| 高清免费成人av| 国产极品尤物在线| 欧美大片专区| 久久久久久国产精品mv| 精品国产亚洲一区二区在线观看 | 欧美成人亚洲成人| 3p在线观看| 在线观看国产精品淫| 国内av一区二区三区| 日韩av在线导航| 你懂的网站在线| 精品日韩美女的视频高清| aaaaa级少妇高潮大片免费看| 日日噜噜夜夜狠狠视频欧美人 | 亚洲毛片aa| 精品99在线| 亚洲影院在线看| www.久久久.com| 成人欧美一区二区三区黑人孕妇| 黄av在线播放| 日韩在线观看精品| 好吊色一区二区三区| 日韩欧美在线中文字幕| 一区二区三区在线播放视频| 国产欧美一区二区精品仙草咪| 日韩人妻无码一区二区三区| 91毛片在线观看| 国产人妻一区二区| 日本一区二区视频在线观看| 色www亚洲国产阿娇yao| 国产精品久久影院| 激情五月激情综合| 亚洲人吸女人奶水| 欧美国产精品一二三| 亚洲大片精品永久免费| 中文字幕在线观看免费视频| 欧美午夜视频一区二区| 国产喷水在线观看| 亚洲精品乱码久久久久久日本蜜臀| 亚洲二区在线播放| 国产视频一区二区在线| 免费黄色在线播放| 日韩激情中文字幕| 在线看的黄色网址| 国产一区二区按摩在线观看| a级大片免费看| 成人深夜福利app| 日本高清www| 亚洲同性gay激情无套| 中国毛片直接看| 国产精品全国免费观看高清| 成年人一级黄色片| 亚洲色图视频免费播放| 久久一二三四区| 日韩欧美亚洲成人| 91久久精品无码一区二区| 日韩亚洲欧美在线| 国产麻豆免费视频| 精品电影一区二区| 男女污污视频在线观看| 久久伊人精品一区二区三区| 国产精品69xx| 久久久久久国产| 日韩电影免费观| 91在线无精精品一区二区| 97人人做人人爽香蕉精品| 91网免费观看| 少妇一区二区视频| 成人一区二区av| 久久看片网站| 国产又大又黄又粗的视频| 国产在线看一区| 国产欧美精品一二三| 97se亚洲国产综合自在线观| 中文国语毛片高清视频| 欧美国产成人精品| 国产一级生活片| 欧美午夜精品一区二区蜜桃 | 国产美女久久| 国产精品天天狠天天看| av成人资源网| 精品欧美一区二区三区久久久| 久久美女视频| 黑人糟蹋人妻hd中文字幕| 九色综合狠狠综合久久| 中文字幕xxx| 一区二区三区免费观看| 久久久精品视频在线| 欧美在线高清视频| 天堂中文资源在线观看| 亚洲欧美国产一本综合首页| 女人天堂av在线播放| 国产免费亚洲高清| 免费欧美激情| 亚洲精品中文综合第一页| 亚洲一区二区三区| 中文字幕一区二区三区四区在线视频| 日本成人中文字幕在线视频| 日本黄色动态图| 一区二区三区日本| 在线观看日韩中文字幕| 91黄色免费观看| 一本色道久久综合亚洲| 亚洲日韩欧美视频一区| 激情国产在线| 韩国成人动漫在线观看| 国产精品片aa在线观看| 成年人网站国产| 日本午夜精品视频在线观看| 亚洲国产精品成人综合久久久| 一区二区三区美女视频| 国产精品美女久久久久av爽| 欧美成人一区二区| 亚洲奶水xxxx哺乳期| 欧美亚洲国产另类| 狠狠久久伊人| 亚洲伊人婷婷| 麻豆精品久久久| 萌白酱视频在线| 欧美日韩国产免费一区二区| av色图一区| 国产在线视频一区| 欧美午夜18电影| 欧美黑人经典片免费观看| 另类调教123区| 国精产品久拍自产在线网站| 亚洲成人av一区| 亚洲va欧美va| 欧美国产日韩免费| yy6080久久伦理一区二区| 日韩三级在线播放| 奇米色777欧美一区二区| 亚洲激情图片网| 欧美精品色综合| caoporn免费在线| 国产乱码一区| 另类av一区二区| 成人黄色a级片| 欧美精品 日韩| 深夜国产在线播放| 国产精品欧美日韩一区二区| 久久精品国产www456c0m| 亚洲理论中文字幕| 一区二区三区成人在线视频| 日本xxxx人| 成人97在线观看视频| 99久久香蕉| 人妻精品无码一区二区三区| 国产婷婷一区二区| 国产精品久免费的黄网站| 欧美哺乳videos| 性欧美freesex顶级少妇| 国产精品大全| 一精品久久久| 欧美肉大捧一进一出免费视频| 一本色道亚洲精品aⅴ| 男女啪啪在线观看| 国产成人中文字幕| 亚洲91视频| 亚洲一区二区三区综合| 欧美最新大片在线看| 国产在线看片| 91精品视频观看| av成人毛片| 日韩 中文字幕| 91.com视频| 午夜不卡视频| 国产欧美日韩亚洲精品| 国产一区三区在线播放| av免费播放网址| 久久网这里都是精品| 国产一级免费视频| 久久成人精品视频| 久久99国产精品视频| 欧美黄网站在线观看| 91网站在线播放| 精品国产av一区二区三区| 不卡av日日日|