国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

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

2024-07-10 13:07:25
字體:
供稿:網(wǎng)友

同步套接字通信

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

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

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

客戶端建立一個socket,設(shè)置好服務(wù)器端的ip和提供服務(wù)的端口,發(fā)出連接請求,接收到服務(wù)的確認(rèn)后,盡力連接,開始與服務(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解析地址的尋址方案。internetwork標(biāo)示需要ip版本4的地址,internetworkv6需要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為internet主機地址信息提供容器,該容器提供存有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.internetwork,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ù)量提供標(biāo)準(zhǔn)值)none 不對次調(diào)用使用標(biā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是當(dāng)前線程阻塞一段時間thread.sleep(timeout.infinite)是線程休眠,直到被調(diào)用thread.interrrupt的另一個線程中斷或被thread.abort中止。

一個線程不能對另一個調(diào)用sleep,可以使用thread.suspend來暫停線程,當(dāng)線程對自身調(diào)用thread.suspend將阻塞,直到該線程被另一個線程繼續(xù),當(dāng)一個線程對另一個調(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,則當(dāng)調(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ò)通信的最終地址不是主機地址,是可以描述進程的摸中標(biāo)識符。tcp/ip提出協(xié)議端口porotocol port端口,表示通信進程。

       進程通過os調(diào)用綁定連接端口,而在傳輸層傳輸給該端口的數(shù)據(jù)傳入進程中處理,同樣在進程的數(shù)據(jù)需要傳給傳輸層也是通過綁定端口實現(xiàn)。進程對端口的操作相當(dāng)于對os中的i/o文件進行操作,每一個端口也對應(yīng)著一個端口號,tcp/ip協(xié)議分為tcp和udp,雖然有相同port number的端口,但是互相也不沖突。 端口號的分配有全局分配,本地分配(動態(tài)分配),當(dāng)進程需要訪問傳輸層,os分配給進程一個端口號。全局分配,就是os固定分配的端口,標(biāo)準(zhǔn)的服務(wù)器都有固定的全局公認(rèn)的端口號提供給服務(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é)議+本地地址+本地端口號+遠(yuǎn)程地址+遠(yuǎn)程端口號 五元組 全相關(guān)。

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

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

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

字節(jié)流:把傳輸中的報文當(dāng)作一個字節(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.       打開通信通道,通知本地主機,在某一個公認(rèn)地址上接收客戶請求

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.internetwork,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.internetwork,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ā)送和接收端

tcp協(xié)議的接收端

using system.net.sockets ; //使用到tcplisten類

using system.threading ; //使用到線程 

using system.io ; //使用到streamreader類

         int port = 8000; //定義偵聽端口號

         private thread ththreadread; //創(chuàng)建線程,用以偵聽端口號,接收信息

         private tcplistener tltcplisten; //偵聽端口號

         private bool blistener = true; //設(shè)定標(biāo)示位,判斷偵聽狀態(tài)

         private networkstream nsstream; //創(chuàng)建接收的基本數(shù)據(jù)流 

         private streamreader srread;

         private system.windows.forms.statusbar statusbar1;

         private system.windows.forms.button button1;

         private system.windows.forms.listbox listbox1; //從網(wǎng)絡(luò)基礎(chǔ)數(shù)據(jù)流中讀取數(shù)據(jù)

         private tcpclient tcclient ;

          private void listen ( )

         {

              try

              {

                   tltcplisten = new tcplistener ( port ) ; //以8000端口號來初始化tcplistener實例

                   tltcplisten.start ( ) ; //開始監(jiān)聽

                   statusbar1.text = "正在監(jiān)聽..." ;

                   tcclient = tltcplisten.accepttcpclient ( ) ; //通過tcp連接請求

                   nsstream = tcclient.getstream ( ) ; //獲取用以發(fā)送、接收數(shù)據(jù)的網(wǎng)絡(luò)基礎(chǔ)數(shù)據(jù)流

                   srread=new streamreader(nsstream);//以得到的網(wǎng)絡(luò)基礎(chǔ)數(shù)據(jù)流來初始化streamreader實例

 

                   statusbar1.text = "已經(jīng)連接!";

 

                    while( blistener ) //循環(huán)偵聽

                   {

                       string smessage = srread.readline();//從網(wǎng)絡(luò)基礎(chǔ)數(shù)據(jù)流中讀取一行數(shù)據(jù)

                       if ( smessage == "stop" ) //判斷是否為斷開tcp連接控制碼

                       {

                            tltcplisten.stop(); //關(guān)閉偵聽

                            nsstream.close(); //釋放資源

                            srread.close();

                            statusbar1.text = "連接已經(jīng)關(guān)閉!" ;

                            ththreadread.abort(); //中止線程

                            return;

                       }

                       string stime = datetime.now.toshorttimestring ( ) ; //獲取接收數(shù)據(jù)時的時間

                       listbox1.items.add ( stime + " " + smessage ) ;

                   }

              }

              catch ( system.security.securityexception )

              {

                   messagebox.show ( "偵聽失敗!" , "錯誤" ) ;

              }

         }

         //開始監(jiān)聽

         private void button1_click(object sender, system.eventargs e)

         {

              ththreadread = new thread ( new threadstart ( listen ) );

              ththreadread.start();//啟動線程          

              button1.enabled=false;

         }

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

         protected override void dispose( bool disposing )

         {

              try

              {

                   tltcplisten.stop(); //關(guān)閉偵聽

                   nsstream.close();

                   srread.close();//釋放資源

                   ththreadread.abort();//中止線程

              }

              catch{}

              if( disposing )

              {

                   if (components != null)

                   {

                       components.dispose();

                   }

             }

              base.dispose( disposing );

         }

tcp協(xié)議的發(fā)送端

using system.net.sockets; //使用到tcplisten類

using system.threading; //使用到線程

using system.io; //使用到streamwriter類

using system.net; //使用ipaddress類、iphostentry類等

          private streamwriter swwriter; //用以向網(wǎng)絡(luò)基礎(chǔ)數(shù)據(jù)流傳送數(shù)據(jù) 

         private networkstream nsstream; //創(chuàng)建發(fā)送數(shù)據(jù)的網(wǎng)絡(luò)基礎(chǔ)數(shù)據(jù)流 

         private tcpclient tcpclient;

         private system.windows.forms.button button1;

         private system.windows.forms.textbox textbox1;

         private system.windows.forms.button button2;

         private system.windows.forms.textbox textbox2;

         private system.windows.forms.statusbar statusbar1;

         private system.windows.forms.label label1;

         private system.windows.forms.label label2; //通過它實現(xiàn)向遠(yuǎn)程主機提出tcp連接申請 

         private bool tcpconnect = false; //定義標(biāo)識符,用以表示tcp連接是否建立

          //連接 

         private void button1_click(object sender, system.eventargs e)

         {

              ipaddress ipremote ;

              try

              {

                   ipremote = ipaddress.parse ( textbox1.text ) ;

              }

              catch //判斷給定的ip地址的合法性

              {

                   messagebox.show ( "輸入的ip地址不合法!" , "錯誤提示!" ) ;

                   return ;

              }

              iphostentry iphost ;

              try

              {

                   iphost = dns.resolve ( textbox1.text ) ; 

              }

              catch //判斷ip地址對應(yīng)主機是否在線

              {

 

                   messagebox.show ("遠(yuǎn)程主機不在線!" , "錯誤提示!" ) ;

                   return ;

              }

              string shostname = iphost.hostname ;

              try

              {

                   tcpclient tcpclient = new tcpclient(shostname,8000);//對遠(yuǎn)程主機的8000端口提出tcp連接申請

                   nsstream = tcpclient.getstream();//通過申請,并獲取傳送數(shù)據(jù)的網(wǎng)絡(luò)基礎(chǔ)數(shù)據(jù)流  

                   swwriter = new streamwriter(nsstream);//使用獲取的網(wǎng)絡(luò)基礎(chǔ)數(shù)據(jù)流來初始化streamwriter實例

                   button1.enabled = false ;

                   button2.enabled = true ;

                   tcpconnect = true ;

                   statusbar1.text = "已經(jīng)連接!" ;

              }

              catch

              {

                   messagebox.show ( "無法和遠(yuǎn)程主機8000端口建立連接!" , "錯誤提示!" ) ;

                   return ;

              }

         }

          //發(fā)送

         private void button2_click(object sender, system.eventargs e)

         {

              if (textbox2.text !="")

              {

                   swwriter.writeline(textbox2.text);//刷新當(dāng)前數(shù)據(jù)流中的數(shù)據(jù)

                   swwriter.flush();

              }

              else

              {

                   messagebox.show("發(fā)送信息不能為空!","錯誤提示!");

              }

         }

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

         protected override void dispose( bool disposing )

         {

              if ( tcpconnect )

              {

                   swwriter.writeline ( "stop" ) ; //發(fā)送控制碼  

                   swwriter.flush (); //刷新當(dāng)前數(shù)據(jù)流中的數(shù)據(jù)  

                   nsstream.close (); //清除資源

                   swwriter.close ();

              }

              if( disposing )

              {

                   if (components != null)

                   {

                       components.dispose();

                   }

              }

              base.dispose( disposing );

         }

異步套接字

beginaccept

public iasyncresult beginaccept{asynccallback callback,object state}

asynccallback異步回調(diào)方法 object state自定義對象, 返回iasyncresult

using system;

namespace mysocket

{

       public class  stateobject

{

       public stateobject(){構(gòu)造函數(shù)邏輯}

}

}à>

using system;

using system.net;

using system.net.sockets;

using system.threading;

using system.text;

namespace mysocket

{

       public class stateobject

{

       public socket worksocket=null;

       public const int buffersize=1024;

       public byte[] buffer=new byte[buffersize];

       public stringbuilder sb=new stringbuilder();

       public stateobject()

       {}

}

}

實現(xiàn)主機綁定和端口監(jiān)聽:

private ipaddress myip=ipaddress.parse(“127.0.0.1”);

private ipendpoint myserver;

private socket mysocket;

private socket handler;

private static manualresetevent myreset =new manualresetevent(false);

try

{

       iphostentry myhost=new iphostentry();

       myhost=dns.gethostbyname(“”);

       string ipstring =myhost.addresslist[0].tostring();

       myip=ipaddress.parse(ipstring);

}

catch{messagebox.show(“您輸入的ip地址格式不正確,重新輸入!”);}

try

{

       myserver=new ipendpoint(myip,int32.parse(“port”));

       mysocket=new socket(addressfamily.internetwork,sockettype.stream,protocol.tcp);

       mysocket.bind(myserver);

       mysocket.listen(50);

       thread thread=new thread(new threadstart(target));

       thread.start();

}

catch(exception ee){}

線程target

private void target()

{

       while(true)

{

       myreset.reset();

       mysocket.beginaccept(new asynccallback(acceptcallback),mysocket);

       myreset.waitone();

}

}

異步回調(diào)方法acceptcallback

private void acceptcallback(iasyncresault ar)

{

       myreset.set();

       socket listener=(socket)ar.asyncstate;

       handler=listener.endaccept(ar);

       stateobject state=new stateobject();

       state.worksocket=handler;

       try

       {

       byte[] bytedata=system.text.encoding.bigendianunicode.getbytes(“通話!”+”/n/r”);

    handler.beginsend(byutedata,0,bytedata.length,0,new asynccallback(sendcallback),handler);

}

catch(exception ee)

{messagebox.show(ee.message);}

thread thread=new thread(new threadstart(begreceive));

thread.start();

}

 

多線程:

每個窗體自己都在不同的線程上面運行,如果需要在窗體之間交互,需要在線程之間交互

當(dāng)線程sleep,系統(tǒng)就使之退出執(zhí)行隊列,當(dāng)睡眠結(jié)束,系統(tǒng)產(chǎn)生時鐘中斷,使該線程回到執(zhí)行隊列中,回復(fù)線程的執(zhí)行。

如果父線程先于子線程結(jié)束,那么子線程在父線程結(jié)束的時候被迫結(jié)束,thread.join()是父線程等待子線程結(jié)束。abort帶來的是不可回復(fù)的終止線程

起始線程為主線程,前臺線程全部結(jié)束,則主線程可以終止,后臺線程無條件終止。

前臺線程不妨礙程序終止,一旦進程的所有前臺線程終止,則clr調(diào)用任意一個還存活的后臺線程的abort來徹底終止進程。

掛起,睡眠(阻塞,暫停)

thread.suspend不會使線程立即停止執(zhí)行,直到線程到達安全點的時候它才可以將該線程掛起,如果線程尚未運行或這已經(jīng)停止,則不能被掛起,調(diào)用thread.resume使另一個線程跳出掛起狀態(tài),繼續(xù)執(zhí)行。

一個線程不能對另一個線程調(diào)用sleep,但是可以suspend。

lock可以把一段代碼定義為互斥段critical section 互斥段在一個時刻內(nèi)只允許一個線程進入執(zhí)行,其他線程必須等待

多線程公用對象,不應(yīng)該使用lock,monitor提供了線程共享資源的方案,monitor可以鎖定一個對象,線程只有得到鎖才可以對該對象進行操作

一個進程開始至少有一個主線程。系統(tǒng)加載程序時創(chuàng)建主執(zhí)行線程

消息隊列與線程相關(guān)

一開始創(chuàng)建線程就產(chǎn)生消息隊列了,一個線程可以創(chuàng)建多個窗體,而發(fā)給這些窗體的消息都同意發(fā)送到同一個消息隊列中了,消息結(jié)構(gòu)中有msg.hwnd指出該條消息與哪個窗體相關(guān)

dispatchmessage()函數(shù)依照這個保證消息分派處理自動化而且不會出錯。

線程控制方法:

start線程開始運行

sleep 是線程暫停一段指定時間

suspend 線程在到達安全點后暫停

abort 線程到達安全點后停止

resume 重新啟動掛起的線程

join 當(dāng)前線程等待其他線程運行結(jié)束。如果使用超時值,且線程在分配的時間內(nèi)結(jié)束,方法返回true

安全點:代碼中的某些位置,這些位置公共語言運行時可以安全的執(zhí)行自動垃圾回收,即釋放未使用的變量并回收內(nèi)存,調(diào)用線程的abort和suspend方法時,公共語言運行時將分析代碼并確定線程停止運行的適當(dāng)位置。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 芮城县| 新津县| 阜康市| 融水| 西华县| 都昌县| 扶余县| 四川省| 循化| 盈江县| 山东省| 新郑市| 金寨县| 革吉县| 政和县| 大洼县| 湾仔区| 栖霞市| 罗田县| 县级市| 信阳市| 澳门| 许昌县| 北流市| 石嘴山市| 林芝县| 新巴尔虎左旗| 准格尔旗| 名山县| 石泉县| 高陵县| 临沂市| 保德县| 驻马店市| 屏南县| 泌阳县| 双城市| 贵南县| 阿勒泰市| 东城区| 新民市|