日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#.net同步异步SOCKET通讯和多线程总结(转)

發(fā)布時間:2023/12/20 C# 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#.net同步异步SOCKET通讯和多线程总结(转) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

C#.net同步異步SOCKET通訊和多線程總結(jié)

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

同步套接字通信

Socket支持下的網(wǎng)上點對點的通信

服務(wù)端實現(xiàn)監(jiān)聽連接,客戶端實現(xiàn)發(fā)送連接請求,建立連接后進行發(fā)送和接收數(shù)據(jù)的功能

服務(wù)器端建立一個socket,設(shè)置好本機的ip和監(jiān)聽的端口與socket進行綁定,開始監(jiān)聽連接請求,當接收到連接請求后,發(fā)送確認,同客戶端建立連接,開始與客戶端進行通信。

客戶端建立一個socket,設(shè)置好服務(wù)器端的IP和提供服務(wù)的端口,發(fā)出連接請求,接收到服務(wù)的確認后,盡力連接,開始與服務(wù)器進行通信。

服務(wù)器端和客戶端的連接及它們之間的數(shù)據(jù)傳送均采用同步方式。

?

Socket

Socket是tcp\ip網(wǎng)絡(luò)協(xié)議接口。內(nèi)部定義了許多的函數(shù)和例程。可以看成是網(wǎng)絡(luò)通信的一個端點。在網(wǎng)絡(luò)通信中需要兩個主機或兩個進程。通過網(wǎng)絡(luò)傳遞數(shù)據(jù),程序在網(wǎng)絡(luò)對話的每一端需要一個socket。

?????? Tcp/IP傳輸層使用協(xié)議端口將數(shù)據(jù)傳送給一個主機的特定應(yīng)用程序,協(xié)議端口是一個應(yīng)用程序的進程地址。傳輸層模塊的網(wǎng)絡(luò)軟件模塊要于另一個程序通信,它將使用協(xié)議端口,socket是運行在傳輸層的api,使用socket建立連接發(fā)送數(shù)據(jù)要指定一個端口給它。

Socket:

Stream Socket流套接字 Socket提供雙向、有序、無重復(fù)的數(shù)據(jù)流服務(wù),出溜大量的網(wǎng)絡(luò)數(shù)據(jù)。

Dgram socket數(shù)據(jù)包套接字 支持雙向數(shù)據(jù)流,不保證傳輸?shù)目煽啃浴⒂行颉o重復(fù)。

Row socket 原始套接字 訪問底層協(xié)議

建立socket 用C#

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

構(gòu)造新的socket對象:socket原型:

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

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

SocketType參數(shù)指定socket類型Raw支持基礎(chǔ)傳輸協(xié)議訪問,Stream支持可靠,雙向,基于連接的數(shù)據(jù)流。

ProtocolType表示socket支持的網(wǎng)絡(luò)協(xié)議

?

定義主機對象:

IPEndPoint類:IPEndPoint構(gòu)造方法? 位置:System.Net

原型:1)?? public IPEndPoint(IPAddress address,int port)???? 2)public IPEndPoint(long address,int port) 參數(shù)1整型int64如123456,參數(shù)2端口int32

主機解析:

利用DNS服務(wù)器解析主機,使用Dns.Resolve方法

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

Dns.GetHostByName獲取本地主機名稱

原型:public static IPHostEntry GetHostByName(string hostname)

GetHostByAddress

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

?

端口綁定和監(jiān)聽:

同步套接字服務(wù)器主機的綁定和端口監(jiān)聽

Socket類的Bind(綁定主機),Listen(監(jiān)聽端口),Accept(接收客戶端的連接請求)

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

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

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

發(fā)送數(shù)據(jù):方法1:socket類的send方法二.NetworkStream類Write

send原型:public int Send(byte[] buffer) 字節(jié)數(shù)組?

public int Send(byte[],SocketFlags)原型2說明,SocketFlags成員列表:DontRoute(不使用路由表發(fā)送),MaxIOVectorLength(為發(fā)送和接收數(shù)據(jù)的wsabuf結(jié)構(gòu)數(shù)量提供標準值)None 不對次調(diào)用使用標志) OutOfBand(消息的部分發(fā)送或接收)Partial(消息的部分發(fā)送或接收) Peek(查看傳入的消息)

原型三:public int Send(byte[],int,SocketFlags) 參數(shù)二要發(fā)送的字節(jié)數(shù)

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

演示:

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數(shù)組全部發(fā)送

.NetWordStream類的Write方法發(fā)送數(shù)據(jù)

原型:public override void write(byte[] buffer,int offset,int size) 字節(jié)數(shù)組,開始字節(jié)位置,總字節(jié)數(shù)

?

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

接收數(shù)據(jù):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方法接收數(shù)據(jù)

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

線程

線程創(chuàng)建:System.Threading空間下的Thread類的構(gòu)造方法:

原型: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)是線程休眠,直到被調(diào)用Thread.Interrrupt的另一個線程中斷或被Thread.Abort中止。

一個線程不能對另一個調(diào)用Sleep,可以使用Thread.Suspend來暫停線程,當線程對自身調(diào)用Thread.Suspend將阻塞,直到該線程被另一個線程繼續(xù),當一個線程對另一個調(diào)用,該調(diào)用就成為使另一個線程暫停的非阻塞調(diào)用。調(diào)用Thread.Resume使另一個線程跳出掛起狀態(tài)并使該線程繼續(xù)執(zhí)行,而與調(diào)用Thread.Suspend的次數(shù)無關(guān)

線程休眠: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方法引發(fā)ThreadAbortException,開始中止此線程的過程,是一個可以由應(yīng)用程序代碼捕獲的特殊異常,ResetAbort可以取消Abort請求,可以組織ThreadAbortException終止此線程,線程不一定會立即終止,根本不終止。

對尚未啟動的線程調(diào)用Abort,則當調(diào)用Start時該線程將終止。對已經(jīng)掛起的線程調(diào)用Abort,則該線程將繼續(xù),然后終止。對阻塞或正在休眠的線程調(diào)用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命令集,模式為開-讀/寫-關(guān) open write/read close

用戶進程進行i/o操作

用戶進程調(diào)用打開命令,獲取文件或設(shè)備的使用權(quán),并返回描述文件或設(shè)備的整數(shù),以描述用戶打開的進程,該進程進行讀寫操作,傳輸數(shù)據(jù),操作完成,進程關(guān)閉,通知os對哪個對象進行了使用。

Unix網(wǎng)絡(luò)應(yīng)用編程:BSD的套接字socket,unix的System V 的TLI。

套接字編程的基本概念:

網(wǎng)間進程通信:源于單機系統(tǒng),每個進程在自己的地址范圍內(nèi)進行運行,保證互相不干擾且協(xié)調(diào)工作。操作系統(tǒng)為進程之間的通信提供設(shè)施:

Unix BSD 管道pipe,命名管道named pipe軟中斷信號signal

Unix System V 消息message 共享存儲區(qū) shared memory 信號量semaphore

以上僅限于本機進程之間通信。

端口:網(wǎng)絡(luò)上可以被命名和尋址的通信端口,是操作系統(tǒng)可以分配的一種資源,網(wǎng)絡(luò)通信的最終地址不是主機地址,是可以描述進程的摸中標識符。TCP/IP提出協(xié)議端口porotocol port端口,表示通信進程。

?????? 進程通過os調(diào)用綁定連接端口,而在傳輸層傳輸給該端口的數(shù)據(jù)傳入進程中處理,同樣在進程的數(shù)據(jù)需要傳給傳輸層也是通過綁定端口實現(xiàn)。進程對端口的操作相當于對os中的i/o文件進行操作,每一個端口也對應(yīng)著一個端口號,tcp/ip協(xié)議分為tcp和udp,雖然有相同port number的端口,但是互相也不沖突。 端口號的分配有全局分配,本地分配(動態(tài)分配),當進程需要訪問傳輸層,os分配給進程一個端口號。全局分配,就是os固定分配的端口,標準的服務(wù)器都有固定的全局公認的端口號提供給服務(wù)。小于256的可以作為保留端口。

?????? 地址:網(wǎng)絡(luò)通信中的兩臺機器,可以不再同一個網(wǎng)絡(luò),可能間隔(網(wǎng)關(guān),網(wǎng)橋,路由器等),所以可以分為三層尋址

機器在不同的網(wǎng)絡(luò)則有該網(wǎng)絡(luò)的特定id

同一個網(wǎng)絡(luò)中的機器應(yīng)該有唯一的機器id

一臺機器內(nèi)的進程應(yīng)該有自己的唯一id

通常主機地址=網(wǎng)絡(luò)ID+主機ID? tcp/ip中使用16位端口號來表示進程。

網(wǎng)絡(luò)字節(jié)順序,高價先存,tcp和udp都使用16或32整數(shù)位的高價存儲,在協(xié)議的頭文件中。

半相關(guān):在網(wǎng)絡(luò)中一個進程為協(xié)議+本地地址+端口號=三元組,也叫半相關(guān),表示半部分。

全相關(guān):兩臺機器之間通信需要使用相同協(xié)議

????????????? 協(xié)議+本地地址+本地端口號+遠程地址+遠程端口號 五元組 全相關(guān)。

順序:兩個連續(xù)的報文在網(wǎng)絡(luò)中可能不會通過相同的路徑到達,所以接收的順序會和發(fā)送的順序不一致。順序是接收順序與發(fā)送順序一致。Tcp/ip提供該功能。

差錯控制:檢查數(shù)據(jù)差錯:檢查和CheckSum機制 檢查連接差錯:雙方確認應(yīng)答機制。

流控制:雙方傳輸數(shù)據(jù)過程中,保證數(shù)據(jù)傳輸速率的機制,保證數(shù)據(jù)不丟失。

字節(jié)流:把傳輸中的報文當作一個字節(jié)序列,不提供任何數(shù)據(jù)邊界。

全雙工/半雙工:兩個方向發(fā)送或一個方向發(fā)送

緩存/帶外數(shù)據(jù):字節(jié)流服務(wù)中,沒有報文邊界,可以同一時刻讀取任意長度的數(shù)據(jù)。為保證傳輸正確或流協(xié)議控制,需要使用緩存,交互型的應(yīng)用程序禁用緩存。

數(shù)據(jù)傳送中,希望不通過常規(guī)傳輸方式傳送給用戶以便及時處理的某一類信息(unix系統(tǒng)的中斷鍵delete,Control-c)、終端流控制符Control-s、Control-q)為帶外數(shù)據(jù)。

客戶/服務(wù)器模式主動請求方式:

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

2.?????? 等待客戶請求到達端口

3.?????? 接收到重復(fù)服務(wù)請求,處理請求發(fā)送應(yīng)答信號。接收到并發(fā)服務(wù)請求。要激活一個新進程處理客戶請求,unix系統(tǒng)fork、exec,新進程處理客戶請求,不需要對其他請求作出應(yīng)答,服務(wù)完成后,關(guān)閉此進程與客戶的通信鏈路。終止

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

5.?????? 關(guān)閉服務(wù)端

客戶方:

1.?????? 打開一通信通道,并連接到服務(wù)器所在主機的特定端口。

2.?????? 向服務(wù)器發(fā)送服務(wù)請求報文,等待并接收應(yīng)答;繼續(xù)提出請求…….

3.?????? 請求結(jié)束以后關(guān)閉通信通道并終止。

1.?????? 客戶與服務(wù)器進程的作用非對稱,編碼不同

2.?????? 服務(wù)進程先于客戶請求而啟動,系統(tǒng)運行,服務(wù)進程一致存在,直到正常退出或強迫退出

套接字類型:

TCP/IP的socket

Sock_stream可靠的面對連接數(shù)據(jù)傳輸,無差錯、無重復(fù)發(fā)送,安照順序發(fā)送接收,內(nèi)設(shè)流量控制,避免數(shù)據(jù)流超限,數(shù)據(jù)為字節(jié)流,無長度限制,ftp流套接字。

Sock_DGRAM 無連接的服務(wù),數(shù)據(jù)包以獨立包的形式發(fā)送,不提供無措保證,數(shù)據(jù)可能丟失重復(fù),發(fā)送接收的順序混亂,網(wǎng)絡(luò)文件系統(tǒng)nfs使用數(shù)據(jù)報式套接字。

Sock_Ram 接口允許較底層協(xié)議,IP,ICMP直接訪問,檢查新的協(xié)議實現(xiàn)或訪問現(xiàn)有服務(wù)中配置的新設(shè)備。

服務(wù)端:

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

???????? }

???????? //開始監(jiān)聽

???????? 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協(xié)議的發(fā)送和接收端

轉(zhuǎn)載于:https://www.cnblogs.com/yuanermen/archive/2009/04/02/1428050.html

總結(jié)

以上是生活随笔為你收集整理的C#.net同步异步SOCKET通讯和多线程总结(转)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。