1. 程式人生 > >c# TCP程式設計

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();