Cnet同步异步SOCKET通讯和多线程总结.docx

上传人:b****5 文档编号:4164185 上传时间:2022-11-28 格式:DOCX 页数:11 大小:22.34KB
下载 相关 举报
Cnet同步异步SOCKET通讯和多线程总结.docx_第1页
第1页 / 共11页
Cnet同步异步SOCKET通讯和多线程总结.docx_第2页
第2页 / 共11页
Cnet同步异步SOCKET通讯和多线程总结.docx_第3页
第3页 / 共11页
Cnet同步异步SOCKET通讯和多线程总结.docx_第4页
第4页 / 共11页
Cnet同步异步SOCKET通讯和多线程总结.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

Cnet同步异步SOCKET通讯和多线程总结.docx

《Cnet同步异步SOCKET通讯和多线程总结.docx》由会员分享,可在线阅读,更多相关《Cnet同步异步SOCKET通讯和多线程总结.docx(11页珍藏版)》请在冰豆网上搜索。

Cnet同步异步SOCKET通讯和多线程总结.docx

Cnet同步异步SOCKET通讯和多线程总结

Cnet同步异步SOCKET通讯和多线程总结【

C#.net同步异步SOCKET通讯和多线程总结【转自博客园】2010-08-2314:

59同步套接字通信

Socket支持下的网上点对点的通信

服务端实现监听连接,客户端实现发送连接请求,建立连接后进行发送和接收数据的功能

服务器端建立一个socket,设置好本机的ip和监听的端口与socket进行绑定,开始监听连接请求,当接收到连接请求后,发送确认,同客户端建立连接,开始与客户端进行通信。

客户端建立一个socket,设置好服务器端的IP和提供服务的端口,发出连接请求,接收到服务的确认后,尽力连接,开始与服务器进行通信。

服务器端和客户端的连接及它们之间的数据传送均采用同步方式。

SocketSocket是tcp\ip网络协议接口。

内部定义了许多的函数和例程。

可以看成是网络通信的一个端点。

在网络通信中需要两个主机或两个进程。

通过网络传递数据,程序在网络对话的每一端需要一个socket。

Tcp/IP传输层使用协议端口将数据传送给一个主机的特定应用程序,协议端口是一个应用程序的进程地址。

传输层模块的网络软件模块要于另一个程序通信,它将使用协议端口,socket是运行在传输层的api,使用socket建立连接发送数据要指定一个端口给它。

Socket:

StreamSocket流套接字Socket提供双向、有序、无重复的数据流服务,出溜大量的网络数据。

Dgramsocket数据包套接字支持双向数据流,不保证传输的可靠性、有序、无重复。

Rowsocket原始套接字访问底层协议

建立socket用C#

命名空间:

usingSystem.Net;usingSystem.Net.Socket;

构造新的socket对象:

socket原型:

Publicsocket(AddressFamilyaddressFamily,SocketTypesockettype,ProtocolTypeprotocolType)

AddressFamily用来指定socket解析地址的寻址方案。

InterNetwork标示需要ip版本4的地址,InterNetworkV6需要ip版本6的地址

SocketType参数指定socket类型Raw支持基础传输协议访问,Stream支持可靠,双向,基于连接的数据流。

ProtocolType表示socket支持的网络协议

定义主机对象:

IPEndPoint类:

IPEndPoint构造方法位置:

System.Net

原型:

1)publicIPEndPoint(IPAddressaddress,intport)2)publicIPEndPoint(longaddress,intport)参数1整型int64如123456,参数2端口int32

主机解析:

利用DNS服务器解析主机,使用Dns.Resolve方法

原型:

publicstaticIPHostEntryResolve(stringhostname)参数:

待解析的主机名称,返回IPHostEntry类值,IPHostEntry为Internet主机地址信息提供容器,该容器提供存有IP地址列表,主机名称等。

Dns.GetHostByName获取本地主机名称

原型:

publicstaticIPHostEntryGetHostByName(stringhostname)

GetHostByAddress

原型:

1)publicstaticIPHostEntryGetHostByAddress(IPAddressaddress)参数:

IP地址2)publicstaticIPHostEntryGetHostByAddress(stringaddress)IP地址格式化字符串

端口绑定和监听:

同步套接字服务器主机的绑定和端口监听

Socket类的Bind(绑定主机),Listen(监听端口),Accept(接收客户端的连接请求)

Bind:

原型:

publicvoidBind(EndPointLocalEP)参数为主机对象IPEndPointListen:

原型:

publicvoidListen(intbacklog)参数整型数值,挂起队列最大值

accept:

原型:

publicsocketaccept()返回为套接字对象

演示程序:

IPAddressmyip=IPAddress.Parse("127.0.0.1");

IPEndPointmyserver=newIPEndPoint(myip,2020);

Socketsock=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

Sock.Bind(myserver);

Sock.Listen(50);

Socketbbb=sock.Accept();

发送数据:

方法1:

socket类的send方法二:

NetworkStream类Writesend原型:

publicintSend(bytebuffer)字节数组

publicintSend(byte,SocketFlags)原型2说明,SocketFlags成员列表:

DontRoute(不使用路由表发送),MaxIOVectorLength(为发送和接收数据的wsabuf结构数量提供标准值)None不对次调用使用标志)OutOfBand(消息的部分发送或接收)Partial(消息的部分发送或接收)Peek(查看传入的消息)

原型三:

publicintSend(byte,int,SocketFlags)参数二要发送的字节数

原型四:

publicintSend(byte,int,int,SocketFlags)参数二为Byte中开始发送的位置

演示:

Socketbbb=sock.Accept();

Bytebytes=newByte[64];

stringsend="aaaaaaaaaaaa";

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

bbb.Send(bytes,bytes.length,0);//将byte数组全部发送

NetWordStream类的Write方法发送数据

原型:

publicoverridevoidwrite(bytebuffer,intoffset,intsize)字节数组,开始字节位置,总字节数

Socketbbb=sock.Accept();

NetWorkStreamstre=newNewWorkStream(bbb);

Byteccc=newByte[512];

stringsendmessage="aaaaaaaaaaaaaa";

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

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

接收数据:

Socket类Receive或NetworkStream类ReadSocket类Receive方法

原型:

publicintReceive(bytebuffer)

2)publicintReceive(byte,SocketFlags)

3)publicintReceive(byte,int,SocketFlags)

4)publicintReceive(byte,int,int,SocketFlags)

.

Socketbbb=sock.Accept();

Byteccc=newByte[512];

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

stringrece=System.Text.Encoding.BigEndianUnicode.GetString(ccc);

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

NetworkStream类的Read方法接收数据

publicoverrideintRead(intbytebuffer,intoffset,intsize)

演示:

bbb=sock.Accept();

NetworkStreamstre=newNetworkStream(bbb);

Byteccc=newByte[512];

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

stringreadMessage=System.Text.Encoding.BigEndianUnicode.GetString(ccc);

线程

线程创建:

System.Threading空间下的Thread类的构造方法:

原型:

publicThread(ThreadStartstart)ThreadStart类型值

Threadthread=newThread(newThreadStart(accp));

Privatevoidaccp(){}//使用线程操作

线程启动

Threadthread=newThread(newThreadStart(accp));

线程暂停与重新启动

启动线程使用Thread.Sleep是当前线程阻塞一段时间Thread.Sleep(Timeout.Infinite)是线程休眠,直到被调用Thread.Interrrupt的另一个线程中断或被Thread.Abort中止。

一个线程不能对另一个调用Sleep,可以使用Thread.Suspend来暂停线程,当线程对自身调用Thread.Suspend将阻塞,直到该线程被另一个线程继续,当一个线程对另一个调用,该调用就成为使另一个线程暂停的非阻塞调用。

调用Thread.Resume使另一个线程跳出挂起状态并使该线程继续执行,而与调用Thread.Suspend的次数无关

线程休眠:

Thread.Sleep(10000);

线程挂起:

Threadthread=newThread(newThreadStart(accp));

Thread.start();

Thread.Suspend();

重新启动:

Threadthread=newThread(newThreadStart(accp));

Thread.start();

Thread.Suspend();

Thread.Resume();

阻塞线程的方法:

thread.Join使用一个线程等待另一个线程停止

Thread.JoinPublicvoidJoin();

PublicvoidJoin(intmillisecondsTimeout);毫秒

PublicboolJoin(TimeSpantimeout);时间间隔类型值

实例:

Threadthread=newThread(newThreadStart(accp));

Thread.start();

Thread.Join(10000);

线程销毁:

Thread.Abort,Thread.InterruptAbort方法引发ThreadAbortException,开始中止此线程的过程,是一个可以由应用程序代码捕获的特殊异常,ResetAbort可以取消Abort请求,可以组织ThreadAbortException终止此线程,线程不一定会立即终止,根本不终止。

对尚未启动的线程调用Abort,则当调用Start时该线程将终止。

对已经挂起的线程调用Abort,则该线程将继续,然后终止。

对阻塞或正在休眠的线程调用Abort,则该线程被中断,然后终止。

Thread类的Abort方法:

PublicvoidAbort()

PublicvoidAbort(objectstateinfo);

演示:

Threadthread=newThread(newThreadStart(accp));

Thread.Start();

Thread.Abort();

Thread.Join(10000);

Socket编程原理:

Unix的i/o命令集,模式为开-读/写-关openwrite/readclose

用户进程进行i/o操作

用户进程调用打开命令,获取文件或设备的使用权,并返回描述文件或设备的整数,以描述用户打开的进程,该进程进行读写操作,传输数据,操作完成,进程关闭,通知os对哪个对象进行了使用。

Unix网络应用编程:

BSD的套接字socket,unix的SystemV的TLI。

套接字编程的基本概念:

网间进程通信:

源于单机系统,每个进程在自己的地址范围内进行运行,保证互相不干扰且协调工作。

操作系统为进程之间的通信提供设施:

UnixBSD管道pipe,命名管道namedpipe软中断信号signalUnixSystemV消息message共享存储区sharedmemory信号量semaphore

以上仅限于本机进程之间通信。

端口:

网络上可以被命名和寻址的通信端口,是操作系统可以分配的一种资源,网络通信的最终地址不是主机地址,是可以描述进程的摸中标识符。

TCP/IP提出协议端口porotocolport端口,表示通信进程。

进程通过os调用绑定连接端口,而在传输层传输给该端口的数据传入进程中处理,同样在进程的数据需要传给传输层也是通过绑定端口实现。

进程对端口的操作相当于对os中的i/o文件进行操作,每一个端口也对应着一个端口号,tcp/ip协议分为tcp和udp,虽然有相同portnumber的端口,但是互相也不冲突。

端口号的分配有全局分配,本地分配(动态分配),当进程需要访问传输层,os分配给进程一个端口号。

全局分配,就是os固定分配的端口,标准的服务器都有固定的全局公认的端口号提供给服务。

小于256的可以作为保留端口。

地址:

网络通信中的两台机器,可以不再同一个网络,可能间隔(网关,网桥,路由器等),所以可以分为三层寻址

机器在不同的网络则有该网络的特定id

同一个网络中的机器应该有唯一的机器id

一台机器内的进程应该有自己的唯一id

通常主机地址=网络ID+主机IDtcp/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的socketSock_stream可靠的面对连接数据传输,无差错、无重复发送,安照顺序发送接收,内设流量控制,避免数据流超限,数据为字节流,无长度限制,ftp流套接字。

Sock_DGRAM无连接的服务,数据包以独立包的形式发送,不提供无措保证,数据可能丢失重复,发送接收的顺序混乱,网络文件系统nfs使用数据报式套接字。

Sock_Ram接口允许较底层协议,IP,ICMP直接访问,检查新的协议实现或访问现有服务中配置的新设备。

异步套接字

BeginAcceptPublicIAsyncResultBeginAccept{AsyncCallbackcallback,objectstate}

AsyncCallback异步回调方法objectstate自定义对象,返回IasyncResultUsingSystem;

NamespacemySocketPublicclassStateobjectPublicStateObject(){构造函数逻辑}

UsingSystem;

UsingSystem.Net;

UsingSystem.Net.Sockets;

UsingSystem.Threading;

UsingSystem.Text;

NamespacemysocketPublicClassStateObjectPublicSocketworksocket=null;

Publicconstintbuffersize=1024;

Publicbytebuffer=newbyte[buffersize];

PublicStringBuildersb=newStringBuilder();

PublicStateObject()

{}

实现主机绑定和端口监听:

PrivateIPAddressmyIP=IPAddress.Parse("127.0.0.1");

PrivateIPEndPointMyServer;

PrivateSocketmySocket;

PrivateSocketHandler;

PrivateStaticManualResetEventmyreset=newManualResetEvent(false);

TryIPHostEntrymyhost=newIPHostEntry();

Myhost=dns.gethostbyName("");

StringIPString=myhost.Addresslist[0].tostring();

Myip=IPAddress.Parse(IPString);

Catch{MessageBox.Show("您输入的IP地址格式不正确,重新输入!

");}

TryMyServer=newIPEndPoint(myIP,Int32.Parse("Port"));

Mysocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,Protocol.Tcp);

Mysocket.Bind(Myserver);

Mysocket.Listen(50);

Threadthread=newThread(newThreadStart(target));

Thread.Start();

Catch(Exceptionee){}

线程targetPrivatevoidtarget()

While(true)

myReset.Reset();

mysocket.BeginAccept(newAsyncCallBack(AcceptCallback),mysocket);

myReset.WaitOne();

异步回调方法AcceptCallBackPrivatevoidAcceptCallback(IAsyncResaultar)

myReset.Set();

SocketListener=(Socket)ar.AsyncState;

Handler=Listener.EndAccept(ar);

StateObjectstate=newStateObject();

State.workSocket=handler;

TryBytebyteData=System.Text.Encoding.BigEndianUnicode.GetBytes("通话!

"+"\n\r");

Handler.BeginSend(byuteData,0,byteData.Length,0,newAsyncCallback(SendCallback),handler);

Catch(Exceptionee)

{MessageBox.Show(ee.Message);}

Threadthread=newThread(newThreadStart(begreceive));

Thread.Start();

多线程:

每个窗体自己都在不同的线程上面运行,如果需要在窗体之间交互,需要在线程之间交互

当线程sleep,系统就使之退出执行队列,当睡眠结束,系统产生时钟中断,使该线程回到执行队列中,回复线程的执行。

如果父线程先于子线程结束,那么子线程在父线程结束的时候被迫结束,Thread.Join()是父线程等待子线程结束。

Abort带来的是不可回复的终止线程

起始线程为主线程,前台线程全部结束,则主线程可以终止,后台线程无条件终止。

前台线程不妨碍程序终止,一旦进程的所有前台线程终止,则clr调用任意一个还存活的后台线程的abort来彻底终止进程。

挂起,睡眠(阻塞,暂停)

Thread.Suspend不会使线程立即停止执行,直到线程到达安全点的时候它才可以将该线程挂起,如果线程尚未运行或这已经停止,则不能被挂起,调用thread.resume使另一个线程跳出挂起状态,继续执行。

一个线程不能对另一个线程调用sleep,但是可以suspend。

Lock可以把一段代码定义为互斥段criticalsection互斥段在一个时刻内只允许一个线程进入执行,其他线程必须等待

多线程公用对象,不应该使用lock,monitor提供了线程共享资源的方案,monitor可以锁定一个对象,线程只有得到锁才可以对该对象进行操作

一个进程开始至少有一个主线程。

系统加载程序时创建主执行线程

消息队列与线程相关

一开始创建线程就产生消息队列了,一个线程可以创建多个窗体,而发给这些窗体的消息都同意发送到同一个消息队列中了,消息结构中有msg.hwnd指出该条消息与哪个窗体相关

DispatchMessage()函数依照这个保证消息分派处理自动化而且不会出错。

线程控制方法:

Start线程开始运行

Sleep是线程暂

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1