您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)如何使用C#基于Socket的TCP通信實(shí)現(xiàn)聊天室的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
具體內(nèi)容如下
套接字(socket)是通信的基石,用于描述IP地址和端口,是一個(gè)通信鏈的句柄,可以用來實(shí)現(xiàn)不同虛擬機(jī)或不同計(jì)算機(jī)之間的通信,是支持TCP/IP協(xié)議的網(wǎng)絡(luò)通信的基本操作單元。它是網(wǎng)絡(luò)通信過程中端點(diǎn)的抽象表示,包含進(jìn)行網(wǎng)絡(luò)通信必須的五種信息:連接使用的協(xié)議,本地主機(jī)的IP地址,本地進(jìn)程的協(xié)議端口,遠(yuǎn)地主機(jī)的IP地址,遠(yuǎn)地進(jìn)程的協(xié)議端口。
應(yīng)用層通過傳輸層進(jìn)行數(shù)據(jù)通信時(shí),TCP會(huì)遇到同時(shí)為多個(gè)應(yīng)用程序進(jìn)程提供并發(fā)服務(wù)的問題。多個(gè)TCP連接或多個(gè)應(yīng)用程序進(jìn)程可能需要通過同一個(gè) TCP協(xié)議端口傳輸數(shù)據(jù)。為了區(qū)別不同的應(yīng)用程序進(jìn)程和連接,許多計(jì)算機(jī)操作系統(tǒng)為應(yīng)用程序與TCP/IP協(xié)議交互提供了套接字(Socket)接口。應(yīng) 用層可以和傳輸層通過Socket接口,區(qū)分來自不同應(yīng)用程序進(jìn)程或網(wǎng)絡(luò)連接的通信,實(shí)現(xiàn)數(shù)據(jù)傳輸?shù)牟l(fā)服務(wù)。
建立Socket連接至少需要一對(duì)套接字,其中一個(gè)運(yùn)行于客戶端,稱為ClientSocket ,另一個(gè)運(yùn)行于服務(wù)器端,稱為ServerSocket 。
套接字之間的連接過程分為三個(gè)步驟:服務(wù)器監(jiān)聽,客戶端請求,連接確認(rèn)。
1、服務(wù)器監(jiān)聽:服務(wù)器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態(tài),實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)狀態(tài),等待客戶端的連接請求
2、客戶端請求:指客戶端的套接字提出連接請求,要連接的目標(biāo)是服務(wù)器端的套接字。為此,客戶端的套接字必須首先描述它要連接的服務(wù)器的套接字,指出服務(wù)器端套接字的地址和端口號(hào),然后就向服務(wù)器端套接字提出連接請求。
3、連接確認(rèn):當(dāng)服務(wù)器端套接字監(jiān)聽到或者說接收到客戶端套接字的連接請求時(shí),就響應(yīng)客戶端套接字的請求,建立一個(gè)新的線程,把服務(wù)器端套接字的描述發(fā)給客戶 端,一旦客戶端確認(rèn)了此描述,雙方就正式建立連接。而服務(wù)器端套接字繼續(xù)處于監(jiān)聽狀態(tài),繼續(xù)接收其他客戶端套接字的連接請求。
創(chuàng)建Socket連接時(shí),可以指定使用的傳輸層協(xié)議,Socket可以支持不同的傳輸層協(xié)議(TCP或UDP),當(dāng)使用TCP協(xié)議進(jìn)行連接時(shí),該Socket連接就是一個(gè)TCP連接。
socket通信:分為同步和異步通信,通信兩端分別為客戶端(Client)和服務(wù)器(Server),,本文簡單介紹一下同步通信及案例
聊天室案例 服務(wù)端
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.Threading; namespace 服務(wù)器 { public partial class Form1 : Form { public Form1() { InitializeComponent(); //在多線程編程中,如果需要使用大到主線程需要進(jìn)行檢查取消 CheckForIllegalCrossThreadCalls = false; } IDictionary<string, Socket> clientList = new Dictionary<string, Socket>(); private void button1_Click(object sender, EventArgs e) { Thread th = new Thread(StartSever); th.IsBackground = true; th.Start(); } void StartSever() { //1.創(chuàng)建服務(wù)器端電話 Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); //2.創(chuàng)建手機(jī)卡 IPAddress ip = IPAddress.Parse(txtIP.Text); //把ip和端口轉(zhuǎn)化為IPEndPoint實(shí)例 IPEndPoint endpoint = new IPEndPoint(ip, int.Parse(txtPort.Text)); //3.將電話卡插入到電話中,綁定端口 server.Bind(endpoint); //4.開始監(jiān)聽電話 server.Listen(20); listMsg.Items.Add("服務(wù)器已成功開啟"); //5.等待接電話 while (true) { //接收接入的一個(gè)客戶端 Socket connectClient = server.Accept(); if (connectClient != null) { string infor = connectClient.RemoteEndPoint.ToString(); clientList.Add(infor, connectClient); listMsg.Items.Add(infor + "加入服務(wù)器"); string msg =infor+"已成功進(jìn)入聊天室"; SendMsg(msg); Thread thread = new Thread(ReciveMsg); thread.IsBackground = true; thread.Start(connectClient); } } } void ReciveMsg(object o) { Socket client = o as Socket; while (true) { try { byte[] arrMsg = new byte[1024 * 1024]; int length = client.Receive(arrMsg); if (length > 0) { string recMsg = Encoding.UTF8.GetString(arrMsg, 0, length); IPEndPoint endpoint = client.RemoteEndPoint as IPEndPoint; listMsg.Items.Add(DateTime.Now + "[" + endpoint.Port.ToString() + "]" + recMsg); SendMsg("[" + endpoint.Port.ToString() + "]" + recMsg); } } catch (Exception) { client.Close(); clientList.Remove(client.RemoteEndPoint.ToString()); } } } private void label1_Click(object sender, EventArgs e) { string ip = IPAddress.Any.ToString(); txtIP.Text = ip; } void SendMsg(string str) { foreach (var item in clientList) { byte[] arrMsg = Encoding.UTF8.GetBytes(str); item.Value.Send(arrMsg); } } private void button2_Click(object sender, EventArgs e) { if (txtMsg.Text!="") { SendMsg(txtMsg.Text); } } } }
客戶端
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.Threading; namespace 服務(wù)器2._12 { public partial class Form1 : Form { public Form1() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false; } Socket Client; private void button1_Click(object sender, EventArgs e) { //創(chuàng)建服務(wù)器端電話 Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); //創(chuàng)建手機(jī)卡 IPAddress ip = IPAddress.Parse(txtIP.Text); IPEndPoint endinput = new IPEndPoint(ip, int.Parse(txtport.Text)); Client.Connect(endinput); Thread th = new Thread(ReciveMsg); th.IsBackground = true; th.Start(Client); } void ReciveMsg(object o) { Socket client = o as Socket; //5.等待接電話 while (true) { byte[] arrlist = new byte[1024*1024]; int length = client.Receive(arrlist); string msg = DateTime.Now + Encoding.UTF8.GetString(arrlist,0,length); listmsg.Items.Add(msg); } } private void button2_Click(object sender, EventArgs e) { if (txtinput.Text!=null) { SendMsg(txtinput.Text); } } void SendMsg(string msg) { byte[] arrMsg = Encoding.UTF8.GetBytes(msg); Client.Send(arrMsg); } } }
感謝各位的閱讀!關(guān)于“如何使用C#基于Socket的TCP通信實(shí)現(xiàn)聊天室”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。