亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#聊天程序服務端與客戶端完整實例代碼

2020-01-24 02:37:59
字體:
來源:轉載
供稿:網友

本文所述為基于C#實現的多人聊天程序服務端與客戶端完整代碼。本實例省略了結構定義部分,服務端主要是邏輯處理部分代碼,因此使用時需要完善一些窗體按鈕之類的。

先看服務端代碼如下:

using System;using System.Drawing;using System.Collections;using System.ComponentModel;using System.Windows.Forms;using System.Data;using System.Net;using System.Net.Sockets;using System.Threading;namespace 多人聊天程序Server端{ /// <summary> /// 應用程序的主入口點。 /// </summary> [STAThread] static void Main() {  Application.Run(new Form1()); } // 啟動服務按鈕 private void button2_Click(object sender, System.EventArgs e) {  try  {  // 必須填寫端口  if(txtPort.Text == "")  {   MessageBox.Show("請先填寫服務端口號!", "提示");   return;  }  Int32 port = Int32.Parse(txtPort.Text); // 獲得端口號  // 創建偵聽的Socket  mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  IPEndPoint localEP = new IPEndPoint(IPAddress.Any, port);  // 將 Socket 綁定到本地的終結點上  mainSocket.Bind(localEP);  // 開始偵聽,最大的連接數是 5  mainSocket.Listen(5);  // 開始一個異步操作接受客戶的連接請求  mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);  // 啟動服務按鈕不可用,停止服務按鈕可用  UpdateControls(true);  }  catch(SocketException se)  {  MessageBox.Show(se.Message, "提示");  } } // 更新“啟動服務按鈕”和“停止服務”按鈕的狀態:是否可用; // 注意:兩個按鈕的狀態是互斥的 private void UpdateControls(bool onServe) {  button2.Enabled = !onServe;  button3.Enabled = onServe;  if(onServe)  {  status.Text = "已啟動服務";  }  else  {  status.Text = "未啟動服務";  } } // 回調函數,當客戶連接上時,將會被調用 public void OnClientConnect(IAsyncResult asyn) {  try  {  // 調用EndAccept完成BeginAccept異步調用,返回一個新的Socket處理與客戶的通信  Socket workerSocket = mainSocket.EndAccept(asyn);  // 增加客戶數目  Interlocked.Increment(ref clientNum);  // 將 workerSocket Socket加入到 ArrayList 中  workerSocketList.Add(workerSocket);  // 發送歡迎信息給連接上服務器的客戶  string msg = "歡迎客戶 " + clientNum + " 登錄服務器/n";  SendWelcomeToClient(msg, clientNum);  // 在線客戶數目改變,必須更新客戶列表  UpdateClientListControl();  // 連接上的客戶接收數據  WaitForData(workerSocket, clientNum);  // 主 Socket 返回,繼續等待其它的連接請求  mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);  }  catch(ObjectDisposedException)  {  System.Diagnostics.Debugger.Log(0,"1","/n OnClientConnection: Socket已經關閉!/n");  }  catch(SocketException se)  {  MessageBox.Show(se.Message, "提示");  } } // 發送歡迎信息給客戶 void SendWelcomeToClient(string msg, int clientNumber) {  // 用UTF8格式來將string信息轉化成byte數組形式  byte[] byData = System.Text.Encoding.UTF8.GetBytes(msg);  // 獲得客戶clientNumber對應的Socket  Socket workerSocket = (Socket)workerSocketList[clientNumber - 1];  // 將數據發給客戶  workerSocket.Send(byData); } // 該類保存當前的socket,它的客戶號還有發送給服務器的數據 public class SocketPacket {  public System.Net.Sockets.Socket currentSocket; // 當前的Socket  public int clientNumber; // 客戶號  public byte[] dataBuffer = new byte[1024]; // 發給服務器的數據  // 構造函數  public SocketPacket(System.Net.Sockets.Socket socket, int clientNumber)  {  currentSocket = socket;  this.clientNumber = clientNumber;  } } // 開始等待客戶發送數據 public void WaitForData(System.Net.Sockets.Socket socket, int clientNumber) {  try  {  if(pfnWorkerCallBack == null)  {   // 當連接上的客戶有寫的操作的時候,調用回調函數   pfnWorkerCallBack = new AsyncCallback(OnDataReceived);  }  SocketPacket socketPacket = new SocketPacket(socket, clientNumber);  socket.BeginReceive(socketPacket.dataBuffer, 0, socketPacket.dataBuffer.Length,            SocketFlags.None, pfnWorkerCallBack, socketPacket);  }  catch(SocketException se)  {  MessageBox.Show (se.Message, "提示");  } } // 當客戶寫數據時,調用以下方法 public void OnDataReceived(IAsyncResult asyn) {  SocketPacket socketData = (SocketPacket)asyn.AsyncState ;  try  {  // EndReceive完成BeginReceive異步調用,返回客戶寫入流的字節數  int iRx = socketData.currentSocket.EndReceive(asyn);  // 加 1 是因為字符串以 '/0' 作為結束標志符  char[] chars = new char[iRx + 1];  // 對客戶發來的信息進行UTF8解碼,存入chars字符數組中  System.Text.Decoder decoder = System.Text.Encoding.UTF8.GetDecoder();  int charLen = decoder.GetChars(socketData.dataBuffer, 0, iRx, chars, 0);  System.String szData = new System.String(chars);  string msg = "客戶 " + socketData.clientNumber + " 發的信息:" + szData;  // 將客戶發的數據加入到信息列表中  AppendToRichEditControl(msg);  // 等待數據  WaitForData(socketData.currentSocket, socketData.clientNumber);  }  catch (ObjectDisposedException )  {  System.Diagnostics.Debugger.Log(0,"1","/nOnDataReceived: Socket已經關閉!/n");  }  catch(SocketException se)  {  if(se.ErrorCode == 10054)  {   // 將客戶斷開連接的信息寫入信息列表中   string msg = "客戶 " + socketData.clientNumber + " 已斷開了連接!" + "/n";   AppendToRichEditControl(msg);   // 移走已關閉的socket   workerSocketList[socketData.clientNumber - 1] = null;   // 更新客戶列表   UpdateClientListControl();  }  else  {   MessageBox.Show (se.Message, "提示");  }  } } // 更新信息列表,該方法可由主線程或其他工作線程所調用 private void AppendToRichEditControl(string msg) {  // 測試看是哪個線程調用了該方法  if (InvokeRequired)  {  // We cannot update the GUI on this thread.  // All GUI controls are to be updated by the main (GUI) thread.  // Hence we will use the invoke method on the control which will  // be called when the Main thread is free  // Do UI update on UI thread  object[] pList = {msg};  txtRecvMsg.BeginInvoke(new UpdateRichEditCallback(OnUpdateRichEdit), pList);  }  else  {  // 創建該控件的主線程直接更新信息列表  OnUpdateRichEdit(msg);  } } // 添加信息到 txtRecvMsg 中 private void OnUpdateRichEdit(string msg) { // txtRecvMsg.AppendText(msg);  txtRecvMsg.Text = txtRecvMsg.Text + msg; } // 更新客戶列表 private void UpdateClientListControl() {  if (InvokeRequired) // Is this called from a thread other than the one created  // the control  {  clientList.BeginInvoke(new UpdateClientListCallback(UpdateClientList), null);  }  else  {  // 創建該控件的主線程直接更新信息列表  UpdateClientList();  } } // 更新客戶列表 void UpdateClientList() {  clientList.Items.Clear(); // 清空客戶列表  for(int i = 0; i < workerSocketList.Count; i++)  {  // 加1,是因為數組從下標0開始,而我們的客戶標號是從1開始  string clientKey = Convert.ToString(i + 1);  Socket workerSocket = (Socket)workerSocketList[i];  if(workerSocket != null)  {   // 將連接著服務器的客戶添加到客戶列表中   if(workerSocket.Connected)   {   clientList.Items.Add(clientKey);   }  }  } } // 停止服務按鈕 private void button3_Click(object sender, System.EventArgs e) {  CloseSockets();  UpdateControls(false);  // 更新客戶列表  UpdateClientListControl(); } // 發送信息按鈕 private void button1_Click(object sender, System.EventArgs e) {  // 如果在線客戶列表不為空,則允許發送信息  if (clientList.Items.Count != 0 )  {  try  {   string msg = txtSendMsg.Text;   msg = "服務器信息: " + msg + "/n";   byte[] byData = System.Text.Encoding.UTF8.GetBytes(msg);   Socket workerSocket = null;   for(int i = 0; i < workerSocketList.Count; i++)   {   workerSocket = (Socket)workerSocketList[i];   if(workerSocket!= null)   {    // 發給所有連接上服務器的客戶    if(workerSocket.Connected)    {    workerSocket.Send(byData);    }   }   }  }  catch(SocketException se)  {   MessageBox.Show(se.Message, "提示");  }  }  else  {  MessageBox.Show("沒有在線客戶,不能發送信息!", "提示");  } } // 清空信息按鈕 private void button4_Click(object sender, System.EventArgs e) {  txtRecvMsg.Clear(); // 清空從客戶發來的信息 } // 關閉窗體按鈕 private void button5_Click(object sender, System.EventArgs e) {  CloseSockets();  Close(); } // 關閉Socket void CloseSockets() {  // 關閉主Socket  if(mainSocket != null)  {  mainSocket.Close();  }  Socket workerSocket = null;  // 關閉客戶 Socket 數組  for(int i = 0; i < workerSocketList.Count; i++)  {  workerSocket = (Socket)workerSocketList[i];  if(workerSocket != null)  {   workerSocket.Close();   workerSocket = null;  }  } } private void Form1_Load(object sender, System.EventArgs e) {  try  {  // 獲得本機的IP地址  txtIP.Text = Dns.Resolve(Dns.GetHostName()).AddressList[0].ToString();  // 啟動時,啟動服務按鈕可用,停止服務按鈕不可用  UpdateControls(false);  }  catch(Exception exc)  {  MessageBox.Show(exc.Message, "提示");  } } }}

客戶端主要實現接收來自服務端返回的消息、實現發送消息的操作界面,創建Socket實例,得到服務器的IP地址,更新控件,連接和斷開等,具體代碼如下:

using System;using System.Drawing;using System.Collections;using System.ComponentModel;using System.Windows.Forms;using System.Data;using System.Net;using System.Net.Sockets;namespace 多人聊天程序Client端{ public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.Label label1; private System.Windows.Forms.TextBox txtIP; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label3; private System.Windows.Forms.RichTextBox txtSendMsg; private System.Windows.Forms.Label label4; private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; private System.Windows.Forms.Button button3; private System.Windows.Forms.Button button4; private System.Windows.Forms.RichTextBox txtRecvMsg; private System.Windows.Forms.TextBox txtPort; private System.Windows.Forms.Button button5; private System.ComponentModel.Container components = null; byte[] m_dataBuffer = new byte[10]; IAsyncResult result; public AsyncCallback pfnCallBack ; private System.Windows.Forms.Label status; private System.Windows.Forms.Label label5; public Socket clientSocket; public Form1() {  InitializeComponent(); } private void InitializeComponent() {  this.label1 = new System.Windows.Forms.Label();  this.txtIP = new System.Windows.Forms.TextBox();  this.label2 = new System.Windows.Forms.Label();  this.txtPort = new System.Windows.Forms.TextBox();  this.label3 = new System.Windows.Forms.Label();  this.txtSendMsg = new System.Windows.Forms.RichTextBox();  this.label4 = new System.Windows.Forms.Label();  this.status = new System.Windows.Forms.Label();  this.txtRecvMsg = new System.Windows.Forms.RichTextBox();  this.button1 = new System.Windows.Forms.Button();  this.button2 = new System.Windows.Forms.Button();  this.button3 = new System.Windows.Forms.Button();  this.button4 = new System.Windows.Forms.Button();  this.label5 = new System.Windows.Forms.Label();  this.button5 = new System.Windows.Forms.Button();  this.SuspendLayout();  // label1  this.label1.AutoSize = true;  this.label1.Location = new System.Drawing.Point(16, 24);  this.label1.Name = "label1";  this.label1.Size = new System.Drawing.Size(60, 17);  this.label1.TabIndex = 0;  this.label1.Text = "服務器IP:";  // txtIP  this.txtIP.Location = new System.Drawing.Point(80, 24);  this.txtIP.Name = "txtIP";  this.txtIP.Size = new System.Drawing.Size(160, 21);  this.txtIP.TabIndex = 1;  this.txtIP.Text = "";  // label2  this.label2.AutoSize = true;  this.label2.Location = new System.Drawing.Point(16, 56);  this.label2.Name = "label2";  this.label2.Size = new System.Drawing.Size(35, 17);  this.label2.TabIndex = 2;  this.label2.Text = "端口:";  // txtPort  this.txtPort.Location = new System.Drawing.Point(80, 56);  this.txtPort.Name = "txtPort";  this.txtPort.Size = new System.Drawing.Size(40, 21);  this.txtPort.TabIndex = 3;  this.txtPort.Text = "";  // label3  this.label3.AutoSize = true;  this.label3.Location = new System.Drawing.Point(16, 96);  this.label3.Name = "label3";  this.label3.Size = new System.Drawing.Size(110, 17);  this.label3.TabIndex = 4;  this.label3.Text = "發送信息給服務器:";  // txtSendMsg  this.txtSendMsg.Location = new System.Drawing.Point(16, 120);  this.txtSendMsg.Name = "txtSendMsg";  this.txtSendMsg.Size = new System.Drawing.Size(224, 88);  this.txtSendMsg.TabIndex = 5;  this.txtSendMsg.Text = "";  // label4  this.label4.AutoSize = true;  this.label4.Location = new System.Drawing.Point(16, 248);  this.label4.Name = "label4";  this.label4.Size = new System.Drawing.Size(60, 17);  this.label4.TabIndex = 6;  this.label4.Text = "連接狀態:";  // status  this.status.Location = new System.Drawing.Point(80, 248);  this.status.Name = "status";  this.status.Size = new System.Drawing.Size(192, 23);  this.status.TabIndex = 7;  // txtRecvMsg  this.txtRecvMsg.Location = new System.Drawing.Point(264, 80);  this.txtRecvMsg.Name = "txtRecvMsg";  this.txtRecvMsg.ReadOnly = true;  this.txtRecvMsg.Size = new System.Drawing.Size(224, 144);  this.txtRecvMsg.TabIndex = 8;  this.txtRecvMsg.Text = "";  // button1  this.button1.Location = new System.Drawing.Point(280, 16);  this.button1.Name = "button1";  this.button1.Size = new System.Drawing.Size(88, 32);  this.button1.TabIndex = 9;  this.button1.Text = "連接";  this.button1.Click += new System.EventHandler(this.button1_Click);  // button2  this.button2.Location = new System.Drawing.Point(384, 16);  this.button2.Name = "button2";  this.button2.Size = new System.Drawing.Size(88, 32);  this.button2.TabIndex = 10;  this.button2.Text = "斷開";  this.button2.Click += new System.EventHandler(this.button2_Click);  // button3  this.button3.Location = new System.Drawing.Point(280, 232);  this.button3.Name = "button3";  this.button3.Size = new System.Drawing.Size(88, 32);  this.button3.TabIndex = 11;  this.button3.Text = "清空信息";  this.button3.Click += new System.EventHandler(this.button3_Click);  // button4  this.button4.Location = new System.Drawing.Point(384, 232);  this.button4.Name = "button4";  this.button4.Size = new System.Drawing.Size(88, 32);  this.button4.TabIndex = 12;  this.button4.Text = "關閉";  this.button4.Click += new System.EventHandler(this.button4_Click);  // label5  this.label5.AutoSize = true;  this.label5.Location = new System.Drawing.Point(264, 64);  this.label5.Name = "label5";  this.label5.Size = new System.Drawing.Size(134, 17);  this.label5.TabIndex = 13;  this.label5.Text = "收到服務器發來的信息:";  // button5  this.button5.Location = new System.Drawing.Point(16, 208);  this.button5.Name = "button5";  this.button5.Size = new System.Drawing.Size(224, 32);  this.button5.TabIndex = 14;  this.button5.Text = "發送信息";  this.button5.Click += new System.EventHandler(this.button5_Click);  // Form1  this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);  this.ClientSize = new System.Drawing.Size(512, 277);  this.Controls.Add(this.button5);  this.Controls.Add(this.label5);  this.Controls.Add(this.button4);  this.Controls.Add(this.button3);  this.Controls.Add(this.button2);  this.Controls.Add(this.button1);  this.Controls.Add(this.txtRecvMsg);  this.Controls.Add(this.status);  this.Controls.Add(this.label4);  this.Controls.Add(this.txtSendMsg);  this.Controls.Add(this.label3);  this.Controls.Add(this.txtPort);  this.Controls.Add(this.label2);  this.Controls.Add(this.txtIP);  this.Controls.Add(this.label1);  this.Name = "Form1";  this.Text = "多人聊天程序Client端";  this.Load += new System.EventHandler(this.Form1_Load);  this.ResumeLayout(false); } #endregion [STAThread] static void Main() {  Application.Run(new Form1()); } // 連接按鈕 private void button1_Click(object sender, System.EventArgs e) {  // IP地址和端口號不能為空  if(txtIP.Text == "" || txtPort.Text == "")  {  MessageBox.Show("請先完整填寫服務器IP地址和端口號!", "提示");  return;  }  try  {  // 創建Socket實例  clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  // 得到服務器的IP地址  IPAddress ipAddress = IPAddress.Parse(txtIP.Text);  Int32 port = Int32.Parse(txtPort.Text);  // 創建遠程終結點  IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);  // 連接到遠程服務器  clientSocket.Connect(remoteEP);  if(clientSocket.Connected)  {   UpdateControls(true);   WaitForData(); // 異步等待數據  }  }  catch(SocketException se)  {  MessageBox.Show (se.Message, "提示");  UpdateControls(false);  } } // 等待數據 public void WaitForData() {  try  {  if(pfnCallBack == null)  {   // 當連接上的客戶有寫的操作的時候,調用回調函數   pfnCallBack = new AsyncCallback(OnDataReceived);  }  SocketPacket socketPacket = new SocketPacket();  socketPacket.thisSocket = clientSocket;  result = clientSocket.BeginReceive(socketPacket.dataBuffer, 0, socketPacket.dataBuffer.Length,   SocketFlags.None, pfnCallBack, socketPacket);  }  catch(SocketException se)  {  MessageBox.Show(se.Message, "提示");  } } // 該類保存Socket以及發送給服務器的數據 public class SocketPacket {  public System.Net.Sockets.Socket thisSocket;  public byte[] dataBuffer = new byte[1024]; // 發給服務器的數據 } // 接收數據 public void OnDataReceived(IAsyncResult asyn) {  try  {  SocketPacket theSockId = (SocketPacket)asyn.AsyncState ;  // EndReceive完成BeginReceive異步調用,返回服務器寫入流的字節數  int iRx = theSockId.thisSocket.EndReceive(asyn);  // 加 1 是因為字符串以 '/0' 作為結束標志符  char[] chars = new char[iRx + 1];  // 用UTF8格式來將string信息轉化成byte數組形式  System.Text.Decoder decoder = System.Text.Encoding.UTF8.GetDecoder();  int charLen = decoder.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0);  System.String szData = new System.String(chars);  // 將收到的信息顯示在信息列表中  txtRecvMsg.Text = txtRecvMsg.Text + szData;  // 等待數據  WaitForData();  }  catch (ObjectDisposedException)  {  System.Diagnostics.Debugger.Log(0,"1","/nOnDataReceived: Socket已經關閉!/n");  }  catch(SocketException se)  {  if(se.ErrorCode == 10054)  {   string msg = "服務器" + "停止服務!" + "/n";   txtRecvMsg.Text = txtRecvMsg.Text + msg;   clientSocket.Close();   clientSocket = null;   UpdateControls(false);  }  else  {   MessageBox.Show(se.Message, "提示");  }  } } // 更新控件。連接和斷開(發送信息)按鈕的狀態是互斥的 private void UpdateControls(bool connected) {  button1.Enabled = !connected;  button2.Enabled = connected;  button5.Enabled = connected;  if(connected)  {  status.Text = "已連接";  }  else  {  status.Text = "無連接";  } } // 斷開按鈕 private void button2_Click(object sender, System.EventArgs e) {  // 關閉Socket  if(clientSocket != null)  {  clientSocket.Close();  clientSocket = null;  UpdateControls(false);  } } // 發送信息按鈕 private void button5_Click(object sender, System.EventArgs e) {  try  {  // 如果客戶與服務器有連接,則允許發送信息  if(clientSocket.Connected)  {   string msg = txtSendMsg.Text + "/n";   // 用UTF8格式來將string信息轉化成byte數組形式   byte[] byData = System.Text.Encoding.UTF8.GetBytes(msg);   if(clientSocket != null)   {   // 發送數據   clientSocket.Send(byData);   }  }  }  catch(Exception se)  {  MessageBox.Show(se.Message, "提示");  } } // 清空按鈕 private void button3_Click(object sender, System.EventArgs e) {  txtRecvMsg.Clear(); // 清空信息列表 } // 關閉按鈕 private void button4_Click(object sender, System.EventArgs e) {  // 關閉Socket  if(clientSocket != null)  {  clientSocket.Close();  clientSocket = null;  }  Close(); // 關閉窗體 } private void Form1_Load(object sender, System.EventArgs e) {  UpdateControls(false); // 初始化時,只有連接按鈕可用 } }}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
伊人伊成久久人综合网站| 亚洲成人1234| 亚洲精品成a人在线观看| 国产第一区电影| 欧美日韩国产999| 欧美在线一区二区视频| 国产精品久久久久久一区二区| 精品亚洲国产成av人片传媒| 热久久视久久精品18亚洲精品| 91在线视频九色| 欧美成人自拍视频| 国产精品欧美一区二区三区奶水| 亚洲欧洲在线看| 日本精品久久久久影院| 国产精品极品美女在线观看免费| 成人国产精品一区二区| 粉嫩av一区二区三区免费野| 国产综合在线观看视频| 国产成人短视频| 91a在线视频| 在线看日韩av| 久久影院中文字幕| 久久久久国产精品一区| 欧美性一区二区三区| 欧美在线视频免费| 国产精品v片在线观看不卡| 国产精品久久久久久久久久小说| 欧美激情一区二区三区高清视频| 日韩中文综合网| 欧美精品www| 国产成人精品亚洲精品| 国产综合久久久久久| 91人成网站www| 中文欧美日本在线资源| 亚洲精品91美女久久久久久久| 国内成人精品视频| 欧美日韩性生活视频| 亚洲最大的网站| 国产一区欧美二区三区| 在线中文字幕日韩| 日韩大陆毛片av| 北条麻妃99精品青青久久| 国产精品久久久久久久久久东京| 欧美日韩亚洲系列| 亚洲欧美日韩中文在线| 2021国产精品视频| 91po在线观看91精品国产性色| 国产精品wwww| 美女性感视频久久久| 青青在线视频一区二区三区| 北条麻妃一区二区三区中文字幕| 亚洲精选在线观看| 久久视频在线观看免费| 欧美黑人xxx| 国产精品自产拍在线观| 国产男女猛烈无遮挡91| 久久国产一区二区三区| 久久久视频免费观看| 亚洲欧洲日产国产网站| 国产午夜精品全部视频播放| 日本19禁啪啪免费观看www| 欧美激情精品久久久久久久变态| 欧美劲爆第一页| 97视频在线观看免费高清完整版在线观看| 国产精品视频26uuu| 亚洲最大激情中文字幕| 中文字幕亚洲综合| 91久久精品国产91性色| 欧美不卡视频一区发布| 亚洲精品成人久久电影| 亚洲精品动漫久久久久| 久久精品国产亚洲精品2020| 日韩电影免费观看在线观看| 亚洲精品久久久久中文字幕二区| 成人中心免费视频| 欧美性开放视频| 日本午夜精品理论片a级appf发布| 91精品综合久久久久久五月天| 91高潮精品免费porn| 91亚洲人电影| 亚洲网在线观看| 91在线观看免费| 成人国产精品免费视频| 日韩美女在线播放| www.日本久久久久com.| 成人淫片在线看| 亚洲精品在线看| 91精品视频观看| 日韩在线视频播放| 国内精品久久久久久久| 国产日韩欧美91| 91视频九色网站| 国产精品在线看| 亚洲精品自拍偷拍| 91久久国产精品| 欧美成年人视频| 精品国产乱码久久久久久虫虫漫画| 黑人欧美xxxx| 自拍偷拍亚洲区| 疯狂蹂躏欧美一区二区精品| 国产日韩中文字幕在线| 综合av色偷偷网| 日韩国产高清视频在线| 日韩一区二区三区在线播放| 日韩av在线资源| 国产亚洲精品91在线| 国产精品欧美一区二区| 亚洲欧美国产va在线影院| 国产99久久精品一区二区 夜夜躁日日躁| 成人福利网站在线观看11| 国产精品久久一区| 粗暴蹂躏中文一区二区三区| 日韩av一区二区在线| 国产日韩精品视频| 97视频免费观看| 久久久久久91香蕉国产| 国产美女主播一区| 91丨九色丨国产在线| 日韩欧美精品中文字幕| 久久成人免费视频| 国产精品久久久久久中文字| 国产精品极品美女粉嫩高清在线| 欧美乱大交xxxxx另类电影| 国产美女久久精品香蕉69| 日韩中文在线中文网在线观看| 国产美女被下药99| 国产亚洲人成a一在线v站| 久久国产一区二区三区| 成人国产精品色哟哟| 富二代精品短视频| 午夜精品久久久久久久久久久久久| 欧美成人激情视频| 最好看的2019的中文字幕视频| 亚洲欧美国产精品久久久久久久| 韩国一区二区电影| 亚洲自拍偷拍色片视频| 4k岛国日韩精品**专区| 中文字幕免费精品一区高清| 国产精品久久久久不卡| 亚洲人成在线一二| 亚洲va国产va天堂va久久| 成人在线中文字幕| 视频一区视频二区国产精品| 国产精品亚洲片夜色在线| 久热精品视频在线观看一区| 欧美性理论片在线观看片免费| 国产精品久久久久77777| 亚洲国产精品va在看黑人| 岛国av一区二区| 国产91九色视频| 日本一区二区在线免费播放| 色狠狠av一区二区三区香蕉蜜桃| 91久久精品一区| 亚洲欧美资源在线| 91精品国产自产在线观看永久| 亚洲丝袜一区在线| 欧美一区二区三区精品电影| 欧美激情免费观看| 亚洲第一综合天堂另类专| 欧美成人精品在线播放| 日韩二区三区在线| 欧美午夜性色大片在线观看| 亚洲无亚洲人成网站77777| 成人性生交大片免费看小说|