C#.net同步非同步SOCKET通訊和多線程總結)

來源:互聯網
上載者:User
C#.net同步非同步SOCKET通訊和多線程總結

來源:http://www.cnblogs.com/Silverlight_Team/archive/2009/03/13/1411136.html

同步通訊端通訊

Socket支援下的網上點對點的通訊

服務端實現監聽串連,用戶端實現發送串連請求,建立串連後進行發送和接收資料的功能

伺服器端建立一個socket,設定好原生ip和監聽的連接埠與socket進行綁定,開始監聽串連請求,當接收到串連請求後,發送確認,同用戶端建立串連,開始與用戶端進行通訊。

用戶端建立一個socket,設定好伺服器端的IP和提供服務的連接埠,發出串連請求,接收到服務的確認後,儘力串連,開始與伺服器進行通訊。

伺服器端和用戶端的串連及它們之間的資料傳送均採用同步方式。

Socket

Socket是tcp\ip網路通訊協定介面。內部定義了許多的函數和常式。可以看成是網路通訊的一個端點。在網路通訊中需要兩個主機或兩個進程。通過網路傳遞資料,程式在網路對話的每一端需要一個socket。

       Tcp/IP傳輸層使用協議連接埠將資料傳送給一個主機的特定應用程式,協議連接埠是一個應用程式的進程地址。傳輸層模組的網路軟體模組要於另一個程式通訊,它將使用協議連接埠,socket是運行在傳輸層的api,使用socket建立串連發送資料要指定一個連接埠給它。

Socket:

Stream Socket流通訊端 Socket提供雙向、有序、無重複的資料流服務,出溜大量的網路資料。

Dgram socket資料包通訊端 支援雙向資料流,不保證傳輸的可靠性、有序、無重複。

Row socket 原始通訊端 訪問底層協議

建立socket 用C#

命名空間:using System.Net;using System.Net.Socket;

構造新的socket對象:socket原型:

Public socket (AddressFamily addressFamily,SocketType sockettype,ProtocolType protocolType)

AddressFamily 用來指定socket解析地址的定址方案。Inte.Network標示需要ip版本4的地址,Inte.NetworkV6需要ip版本6的地址

SocketType參數指定socket類型Raw支援基礎傳輸協議訪問,Stream支援可靠,雙向,基於串連的資料流。

ProtocolType表示socket支援的網路通訊協定

定義主機對象:

IPEndPoint類:IPEndPoint構造方法  位置:System.Net

原型:1)   public IPEndPoint(IPAddress address,int port)     2)public IPEndPoint(long address,int port) 參數1整型int64如123456,參數2連接埠int32

主機解析:

利用DNS伺服器解析主機,使用Dns.Resolve方法

原型:public static IPHostEntry Resolve(string hostname) 參數:待解析的主機名稱,返回IPHostEntry類值,IPHostEntry為Inte.Net主機地址資訊提供容器,該容器提供存有IP地址清單,主機名稱等。

Dns.GetHostByName擷取本地主機名稱

原型:public static IPHostEntry GetHostByName(string hostname)

GetHostByAddress

原型:1)public static IPHostEntry GetHostByAddress(IPAddress address) 參數:IP地址 2)public static IPHostEntry GetHostByAddress(string address) IP地址格式化字串

連接埠綁定和監聽:

同步通訊端伺服器主機的綁定和連接埠監聽

Socket類的Bind(綁定主機),Listen(監聽連接埠),Accept(接收用戶端的串連請求)

Bind:原型:public void Bind(EndPoint LocalEP)參數為主機對象 IPEndPoint

Listen:原型:public void Listen(int backlog) 參數整型數值,掛起隊列最大值

accept:原型:public socket accept() 返回為通訊端對象

示範程式:

IPAddress myip=IPAddress.Parse(“127.0.0.1”);

IPEndPoint myserver=new IPEndPoint(myip,2020);

Socket sock=new Socket(AddressFamily.Inte.Network,SocketType.Stream,ProtocolType.Tcp);

Sock.Bind(myserver);

Sock.Listen(50);

Socket bbb=sock.Accept();

發送資料:方法1:socket類的send方法二.NetworkStream類Write

send原型:public int Send(byte[] buffer) 位元組數組 

public int Send(byte[],SocketFlags)原型2說明,SocketFlags成員列表:DontRoute(不使用路由表發送),MaxIOVectorLength(為發送和接收資料的wsabuf結構數量提供標準值)None 不對次調用使用標誌) OutOfBand(訊息的部分發送或接收)Partial(訊息的部分發送或接收) Peek(查看傳入的訊息)

原型三:public int Send(byte[],int,SocketFlags) 參數二要發送的位元組數

原型四:public int Send(byte[],int,int,SocketFlags) 參數二為Byte[]中開始發送的位置

示範:

Socket bbb=sock.Accept();

Byte[] bytes=new Byte[64];

string send="aaaaaaaaaaaa";

bytes=System.Text.Encoding.BigEndianUnicode.GetBytes(send.ToCharArray());

bbb.Send(bytes,bytes.length,0);//將byte數組全部發送

.NetWordStream類的Write方法發送資料

原型:public override void write(byte[] buffer,int offset,int size) 位元組數組,開始位元組位置,總位元組數

Socket bbb=sock.Accept();

.NetWorkStream stre=new NewWorkStream(bbb);

Byte[] ccc=new Byte[512];

string sendmessage="aaaaaaaaaaaaaa";

ccc=System.Text.Encoding.BigEndianUnicode.GetBytes(sendmessage);

stre.Write(ccc,0,ccc.length);

接收資料:Socket類Receive.NetworkStream類Read

Socket類Receive方法

原型:public int Receive(byte[] buffer)   

2)public int Receive(byte[],SocketFlags)

3)public int Receive(byte[],int,SocketFlags)   

4)public int Receive(byte[],int,int,SocketFlags)

.....

Socket bbb=sock.Accept();

........

Byte[] ccc=new Byte[512];

bbb.Receive(ccc,ccc.Length,0);

string rece=System.Text.Encoding.BigEndianUnicode.GetString(ccc);

richTextBox1.AppendText(rece+"\r\n");

.NetworkStream類的Read方法接收資料

public override int Read(int byte[] buffer,int offset,int size)

示範:bbb=sock.Accept();

.......

.NetworkStream stre=new.NetworkStream(bbb);

Byte[] ccc=new Byte[512];

stre.Read(ccc,0,ccc.Length);

string readMessage=System.Text.Encoding.BigEndianUnicode.GetString(ccc);

線程

線程建立:System.Threading空間下的Thread類的構造方法:

原型:public Thread(ThreadStart start) ThreadStart類型值     

       Thread thread=new Thread(new ThreadStart(accp));

       Private void accp(){}//使用線程操作

線程啟動

Thread thread=new Thread(new ThreadStart(accp));

線程暫停與重新啟動

啟動線程使用Thread.Sleep是當前線程阻塞一段時間Thread.Sleep(Timeout.Infinite)是線程休眠,直到被調用Thread.Interrrupt的另一個線程中斷或被Thread.Abort中止。

一個線程不能對另一個調用Sleep,可以使用Thread.Suspend來暫停線程,當線程對自身調用Thread.Suspend將阻塞,直到該線程被另一個線程繼續,當一個線程對另一個調用,該調用就成為使另一個線程暫停非阻塞調用。調用Thread.Resume使另一個線程跳出掛起狀態並使該線程繼續執行,而與調用Thread.Suspend的次數無關

線程休眠:Thread.Sleep(10000);

線程掛起:Thread thread=new Thread(new ThreadStart(accp));

                Thread.start();

                Thread.Suspend();

重新啟動:Thread thread=new Thread(new ThreadStart(accp));

               Thread.start();

               Thread.Suspend();

               Thread.Resume();

阻塞線程的方法:thread.Join使用一個線程等待另一個線程停止

Thread.Join

Public void Join();

Public void Join(int millisecondsTimeout);毫秒

Public bool Join(TimeSpan timeout);時間間隔類型值

執行個體:Thread thread=new Thread(new ThreadStart(accp));

              Thread.start();

              Thread.Join(10000);

線程銷毀:

Thread.Abort,Thread.Interrupt

Abort方法引發ThreadAbortException,開始中止此線程的過程,是一個可以由應用程式代碼捕獲的特殊異常,ResetAbort可以取消Abort請求,可以組織ThreadAbortException終止此線程,線程不一定會立即終止,根本不終止。

對尚未啟動的線程調用Abort,則當調用Start時該線程將終止。對已經掛起的線程調用Abort,則該線程將繼續,然後終止。對阻塞或正在休眠的線程調用Abort,則該線程被中斷,然後終止。

Thread類的Abort方法:

Public void Abort()

Public void Abort(object stateinfo);

示範:

Thread thread=new Thread(new ThreadStart(accp));

Thread.Start();

Thread.Abort();

Thread.Join(10000);

Socket編程原理:

Unix的i/o命令集,模式為開-讀/寫-關 open write/read close

使用者進程進行i/o操作

使用者進程調用開啟命令,擷取檔案或裝置的使用權,並返回描述檔案或裝置的整數,以描述使用者開啟的進程,該進程進行讀寫操作,傳輸資料,操作完成,進程關閉,通知os對哪個對象進行了使用。

Unix網路應用編程:BSD的通訊端socket,unix的System V 的TLI。

通訊端編程的基本概念:

網間進程通訊:源於單機系統,每個進程在自己的位址範圍內進行運行,保證互相不干擾且協調工作。作業系統為進程之間的通訊提供設施:

Unix BSD 管道pipe,具名管道named pipe非強制中斷訊號signal

Unix System V 訊息message 共用儲存區 shared memory 訊號量semaphore

以上僅限於本機進程之間通訊。

連接埠:網路上可以被命名和定址的通訊連接埠,是作業系統可以分配的一種資源,網路通訊的最終地址不是主機地址,是可以描述進程的摸中標識符。TCP/IP提出協議連接埠porotocol port連接埠,表示通訊進程。

       進程通過os調用綁定串連連接埠,而在傳輸層傳輸給該連接埠的資料傳入進程中處理,同樣在進程的資料需要傳給傳輸層也是通過綁定連接埠實現。進程對連接埠的操作相當於對os中的i/o檔案進行操作,每一個連接埠也對應著一個連接埠號碼,tcp/ip協議分為tcp和udp,雖然有相同port number的連接埠,但是互相也不衝突。 連接埠號碼的分配有全域分配,本地分配(動態分配),當進程需要訪問傳輸層,os分配給進程一個連接埠號碼。全域分配,就是os固定分配的連接埠,標準的伺服器都有固定的全域公認的連接埠號碼提供給服務。小於256的可以作為保留連接埠。

       地址:網路通訊中的兩台機器,可以不再同一個網路,可能間隔(網關,橋接器,路由器等),所以可以分為三層定址

機器在不同的網路則有該網路的特定id

同一個網路中的機器應該有唯一的機器id

一台機器內的進程應該有自己的唯一id

通常主機地址=網路ID+主機ID  tcp/ip中使用16位連接埠號碼來表示進程。

網路位元組順序,高價先存,tcp和udp都使用16或32整數位的高價儲存,在協議的標頭檔中。

半相關:在網路中一個進程為協議+本地地址+連接埠號碼=三元組,也叫半相關,表示半部分。

全相關:兩台機器之間通訊需要使用相同協議

              協議+本地地址+本地連接埠號碼+遠程地址+遠程連接埠號碼 五元組 全相關。

順序:兩個連續的報文在網路中可能不會通過相同的路徑到達,所以接收的順序會和發送的順序不一致。順序是接收順序與發送順序一致。Tcp/ip提供該功能。

差錯控制:檢查資料差錯:檢查和CheckSum機制 檢查串連差錯:雙方確認應答機制。

流量控制:雙方傳輸資料過程中,保證資料轉送速率的機制,保證資料不丟失。

位元組流:把傳輸中的報文當作一個位元組序列,不提供任何資料邊界。

全雙工系統/半雙工:兩個方向發送或一個方向發送

緩衝/帶外資料:位元組流服務中,沒有報文邊界,可以同一時刻讀取任意長度的資料。為保證傳輸正確或流協議控制,需要使用緩衝,互動型的應用程式禁用緩衝。

資料傳送中,希望不通過常規傳輸方式傳送給使用者以便及時處理的某一類資訊(unix系統的中斷鍵delete,Control-c)、終端流量控制符Control-s、Control-q)為帶外資料。

客戶/伺服器模式主動請求方式:

1.       開啟通訊通道,通知本地主機,在某一個公認地址上接收客戶請求

2.       等待客戶請求到達連接埠

3.       接收到重複服務要求,處理請求發送應答訊號。接收到並發服務要求。要啟用一個新進程處理客戶請求,unix系統fork、exec,新進程處理客戶請求,不需要對其他請求作出應答,服務完成後,關閉此進程與客戶的通訊鏈路。終止

4.       返回第二步,等待另一個客戶請求。

5.       關閉服務端

客戶方:

1.       開啟一通訊通道,並串連到伺服器所在主機的特定連接埠。

2.       向伺服器發送服務要求報文,等待並接收應答;繼續提出請求…….

3.       請求結束以後關閉通訊通道並終止。

1.       客戶與伺服器處理序的作用非對稱,編碼不同

2.       服務進程先於客戶請求而啟動,系統運行,服務進程一致存在,直到正常退出或強迫退出

通訊端類型:

TCP/IP的socket

Sock_stream可靠的面對串連資料轉送,無差錯、無重複發送,安照順序發送接收,內設流量控制,避免資料流超限,資料為位元組流,無長度限制,ftp流通訊端。

Sock_DGRAM 不需連線的服務,資料包以獨立包的形式發送,不提供無措保證,資料可能丟失重複,發送接收的順序混亂,網路檔案系統nfs使用資料報式通訊端。

Sock_Ram 介面允許較底層協議,IP,ICMP直接存取,檢查新的協議實現或訪問現有服務中配置的新裝置。

服務端:

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Threading;

Thread mythread ;

Socket socket;

// 清理所有正在使用的資源。

        protected override void Dispose( bool disposing )

         {

              try

             {

           socket.Close();//釋放資源

           mythread.Abort ( ) ;//中止線程

             }

             catch{ }

             if( disposing )

              {

                   if (components != null)

                   {

                       components.Dispose();

                   }

              }

              base.Dispose( disposing );

         }       

         public static IPAddress GetServerIP()

         {

              IPHostEntry ieh=Dns.GetHostByName(Dns.GetHostName());

              return ieh.AddressList[0];

         }

         private void BeginListen()

         {

              IPAddress ServerIp=GetServerIP();

              IPEndPoint iep=new IPEndPoint(ServerIp,8000);

              socket=new

                       Socket(AddressFamily.Inte.Network,SocketType.Stream,ProtocolType.Tcp);

              byte[] byteMessage=new byte[100]; 

              this.label1.Text=iep.ToString();

              socket.Bind(iep); 

//            do

              while(true)

              {

                   try

                   {

                       socket.Listen(5);

                       Socket newSocket=socket.Accept();

                       newSocket.Receive(byteMessage);

                       string sTime = DateTime.Now.ToShortTimeString ( ) ;

string msg=sTime+":"+"Message from:";

msg+=newSocket.RemoteEndPoint.ToString()+Encoding.Default.GetString(byteMessage);

                       this.listBox1.Items.Add(msg);

                   }

                   catch(SocketException ex)

                   {

                       this.label1.Text+=ex.ToString();

                   }

              }

//            while(byteMessage!=null);

         }

         //開始監聽

         private void button1_Click(object sender, System.EventArgs e)

         {

              try

              {

                   mythread = new Thread(new ThreadStart(BeginListen));

                   mythread.Start();

              }

              catch(System.Exception er)

              {

                   MessageBox.Show(er.Message,"完成",MessageBoxButtons.OK,MessageBoxIcon.Stop);

              }

         }

用戶端:

using System.Net;

using System.Net.Sockets;

using System.Text;

         private void button1_Click(object sender, System.EventArgs e)

         {

              BeginSend();      

         }

         private void BeginSend()

         {            

              string ip=this.txtip.Text;

              string port=this.txtport.Text;

              IPAddress serverIp=IPAddress.Parse(ip);           

              int serverPort=Convert.ToInt32(port);

              IPEndPoint iep=new IPEndPoint(serverIp,serverPort); 

              byte[] byteMessage; 

//            do

//            {

                   Socket socket=new Socket(AddressFamily.Inte.Network,SocketType.Stream,ProtocolType.Tcp);

                   socket.Connect(iep);

                   byteMessage=Encoding.ASCII.GetBytes(textBox1.Text);

                   socket.Send(byteMessage);

                   socket.Shutdown(SocketShutdown.Both);

                   socket.Close();

//            }

//            while(byteMessage!=null);

         }

基於TCP協議的發送和接收端

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.