c# TCP程式設計
一、網路協議
1、TCP協議
(1)TCP:傳輸控制協議
(2)是一種固定連線為基礎的協議,可以提供兩臺計算機間的可靠資料傳輸。
(3)TCP可以保證從一端將資料傳送至另一端,資料能夠實時的送達,而且送達的資料排列順序和送出時的順序相同。
(4)面向連線的、可靠的、基於位元組流的傳輸通訊協議。
TCP通訊就像兩個人電話通話,必須先播對方電話,等雙方接通後,才能對話,是點對點的連線。
2、UDP協議
(1)UDP是連線通訊協議,不可靠的資料傳輸,當能夠向若干個目標傳送資料,接收發自若干個源的資料。
(2)UDP以獨立傳送資料包的方式進行。
UDP協議像是村裡的廣播大喇叭,有的人能聽見有的人聽不見,到底都有誰聽到了,廣播的人也不清楚。
3、對比
協議 | TCP | UDP |
傳輸可靠,反饋資料是否送達 | 不可靠,無任何反饋 | |
需要建立連線請求,連線成功後發資料,效率低 | 不建立連線請求,直接傳送資料,效率高 |
4、IP地址
特殊ip:127.0.0.1 不進行網路傳輸,立即返回本地。
c# ip地址封裝:
(1)Dns類:是一個靜態類,它從Internet域名系統中檢索關於特定主機的資訊。
(2)IPAdress類:包含計算機在IP網路上的地址,主要用來提供網路協議地址。
(3)IPHostEntry類:為Internet主機資訊提供容器類。
三、埠及套接字
1、埠:並非真實的物理存在,而是一個假想的連線裝置。
埠一般規定在0-65535之間,0-1023之間的埠號通常用於一些比較知名的網路服務和應用,普通的網路程式應該使用1024以上的埠號,以避免該埠號被另一個應用或系統服務所用。
2、套接字(socket):用於將程式和網路連線起來,套接字是一個假想的連線裝置。
四、C# 網路連線類
(1)Socket類:為網路通訊提供了一套豐富的方法和屬性,主要用於管理連線,實現Berkeley通訊端套接字連線,同時還提供了繫結、網路連線端點及資料傳輸資料所需要的各種方法,提供處理端點連線傳輸等細節所需要的功能。
(2)TCPClient類:通過網路連線、傳送和接收流資料。
(3)TCPListener類:偵聽和接收傳入的連線請求。
(4)UDPClient類:傳送和接收無連線UDP資料報。
一般情況下不需要直接使用Socket類,而是直接使用進一步封裝後TcpListener類、TcpClient類以及UdpClient類來實現。這主要是因為使用Socket編寫程式比較麻煩。
1、套接字:
(1)型別:流套接字、資料報套接字和原始套接字。流套接字用來實現面向連線的Tcp通訊,資料報套接字用來面向無連線的UDP通訊,原始套接字實現IP資料包通訊。
(2)面向連線的套接字之間的連線過程:
伺服器監聽、客戶端請求、連線確認。
伺服器監聽:是指伺服器套接字並不定位具體的客戶端套接字,而是處於等待連線狀態,實時檢測網路狀態。
客戶端請求:是指客戶端的套接字提出連線請求,要連線的目標是伺服器的套接字,為此客戶端套接字必須先描述它要連線的伺服器套接字,指出伺服器套接字的地址和埠,然後再向伺服器套接字提出連線請求。
連線確認:指當伺服器套接字監聽到客戶端套接字的連線請求時,它就響應客戶端套接字的請求,把伺服器套接字的資訊發給客戶端,一旦客戶端接收到這個資訊,連線建立。伺服器套機字繼續監聽其它客戶端的連線請求。
2、實現過程
(1)建立連線
服務端:
//網路連線
private void connectButton_Click(object sender, EventArgs e)
{
IPAddress ipAddress=Dns.GetHostAddress("")[0];//獲取本地IP地址
porttextBox.Text = "8888";//定義埠號
point = new IPEndPoint(ipAddress,Int32.Parse(porttextBox.Text));//獲取ip地址和埠號
socket = new Socket(AddressFamily.InterNetwork, SocketType.StreamProtocolType.Tcp);//建立一個本地套接字物件
socket.Bind(point);//套接字繫結到用於TCP通訊的本地IP地址和埠上
socket.Listen(50);//等待客戶端發出連線嘗試
//Listen方法自動的將客戶連線請求放到請求佇列中,引數指出系統等待使用者程式服務排列隊的連線數,超過客戶端連線數的任何客戶都不能與伺服器進行通訊
//建立接收客戶端的連線請求的執行緒
Thread thread = new Thread(new ThreadStart(ProcessAccept));
thread.Start();
statelabel.Text = "online! monitoring";
connectButton.Text = "已連線";
}
//接收客戶端連線請求
private void ProcessAccept()
{
while (flag)
{
try
{
Socket sk = socket.Accept();//程式執行到Accept方法時會被阻塞,直到接收到客戶端的連線請求,才執行下一句
Work_Process wkp = new Work_Process();
wkp.f = this;
wkp.acceptedSocket = sk;
array1[index_socket] = sk;
index_socket++;
Thread thread = new Thread(new ThreadStart(wkp.Proccess));
thread.Start();
}
catch (Exception ey)
{
MessageBox.Show(ey.Message);
}
}
}
class Work_Process
{
public Socket acceptedSocket;
public Form1 f;
public void Proccess()
{
if (acceptedSocket.Connected)
{
while (true)
{
byte[] receiveByte = new byte[64];
//int t=acceptedSocket.Receive(receiveByte, receiveByte.Length, 0);
acceptedSocket.Receive(receiveByte);
string strInfo = byteToHexStr(receiveByte);
f.UpdateTextBox(receiveByte);
}
}
}
客戶端:
客戶端利用Socket的Connect方法向程式設計主機的端點發起連線請求,並將自身繫結到系統自動分配的端點。
IPAddress remoteHost = IPAddress.Parse("192.168.0.1");
IPEndPoint iep = new IPEndPoint(remoteHost,80);
Socket localSocket= new Socket(AddressFamily.InterNetwork, SocketType.StreamProtocolType.Tcp);//建立一個本地套接字物件
localSocket.Connect(iep);//客戶端和伺服器建立連線之前,系統不會執行Connect語句下面的語句,而處於阻塞狀態,直到連線成功或出現異常為止
(2)傳送和接收訊息
服務端:當服務端接收到客戶端的連線請求成功時,Accept方法將返回包含該客戶端IP地址及埠號資訊的套接字,伺服器可以用該套接字與客戶端通訊。
Socket clientSocket localSocket.Accept();//等待客戶端的連線請求
//建立連線後,利用Send方法向客戶端傳送資訊
clientSocke.Send(Endcoding.ASCII.GetBytes("server send Hello"));
//接收客戶端資訊
byte [] myresult = new Byte [1024];
int receiveNum = clientSocket.Receive(myresult);
客戶端:客戶端可直接使用本地套接字的send方法向伺服器傳送資訊,利用Receive方法接收伺服器資訊。
localSocket.Connect(iep);
//建立連線成功後,向伺服器傳送訊息
String sendMessage ="hello";
localSocket.Send(Encoding.ASCII.GeBytes(sendMessage));
console.WrieLine("向伺服器傳送訊息:{0}",sendMessage);
//接收服務端資訊
byte[] result =new Byte[1024];
localSocket.Receive(result);
(3) 關閉連線
localSocket.Shutdown(SocketShutdown.Both);
localSocket.Close();