C#.net同步异步SOCKET通讯和多线程总结_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > C#.net同步异步SOCKET通讯和多线程总结

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

 2010/12/9 9:13:44  jonsion  http://jonsion.javaeye.com  我要评论(0)
  • 摘要:同步套接字通信Socket支持下的网上点对点的通信服务端实现监听连接,客户端实现发送连接请求,建立连接后进行发送和接收数据的功能服务器端建立一个socket,设置好本机的ip和监听的端口与socket进行绑定,开始监听连接请求,当接收到连接请求后,发送确认,同客户端建立连接,开始与客户端进行通信。客户端建立一个socket,设置好服务器端的IP和提供服务的端口,发出连接请求,接收到服务的确认后,尽力连接,开始与服务器进行通信。服务器端和客户端的连接及它们之间的数据传送均采用同步方式
  • 标签:总结 .net C# 异步socket 多线程 net socket

同步套接字通信?

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

???????? }?

发表评论
用户名: 匿名