学习笔记(TCP应用编程)

作者在 2011-06-24 21:48:31 发布以下内容
TCP简介:
主要特点:
1.面向连接的传输层协议。
2.每个TCP连接只能有两个端点,而且只能一对一的通信,不能一对多点直接通信。
3.能确保传输数据无差错、不丢失、不重复地准确到达接收方,并确保各数据到达的顺序与数据发出的顺序相同。
4.数据以字节流的方式传输。
5.传输的数据无消息边界。
TcpListener类和TcpClient类:
TcpListener类:用来监听和接收传入的连接请求。
TcpListener(IPEndPoint iep);通过IPEndPoint 类型的对象在指定的IP地址和端口监听客户端连接。
TcpListener(IPAddress localAddr,int port);直接指定本机的IP地址和端口号,并通过指定的本机IP地址和端口监听传入的连接请求。
创建了TcpListener对象后,就可以监听客户端的连接请求,在同步工作下,对应有Start()方法、Stop()方法、AcceptSocket()方法和AcceptTcpClient()方法。
TcpClient类:主要用于客户端编程,而服务端程序是通过TcpListener对象的AcceptTcpClient()方法得到TcpClient对象,不要创建TcpClient对象。
四种构造函数形式:
1.TcpClient tcpClient = new TcpClient();默认创建TcpClient对象,自动分配本机(客户端)IP地址和端口号.
tcpClient.Connect("www.abcd.com",51888);
2.TcpClient tcpCilent = new TcpClient(AddressFamily.InterNetwork);创建TcpClient对象,自动分配本机(客户端)IP地址和端口号,使用AddressFamily枚举指定使用哪种网络协议。
tcpClient.Connect("www.abcd.com",51888);
3.TcpClient tcpClient = new TcpClient(IPEndPoint iep);参数iep指定本机(客户端)IP地址很端口号。当客户端存在一个以上的IP地址。
IPAddress[] address = Dns.GetHostAddresses(Dns.GetHostName());
IPEndPort iep = new IPEndPoint(address[0],51888);
TcpClient tcpClient = new TcpClient();
tcpClient.Connect("www.abcd.com",51888);
4.TcpClient(string hostname,int port);hostname:连接的远程主机的DNS名,port表示要连接到的远程主机的端口号。
TcpClient tcpClient = new TcpClient("www.abcd.com",51888);
TcpClient类的常用属性:
属性
含义
Client
获取或设置基础套接字
LingerState
获取或设置套接字保持连接的时间
NoDelay
获取或设置一个值,该值在发送或接收缓冲区未满时禁用延迟
ReceiveBufferSize
获取或设置Tcp接收缓冲区的大小
ReceiveTimeout
获取或设置套接字接收数据的超时时间
SendBufferSize
获取或设置Tcp发送缓冲区的大小
SendTimeout
获取或设置套接字发送数据的超时时间
TcpClient类的常用方法:
方法
含义
Close
释放TcpClient实例,而不关闭基础连接
Connect
用指定的主机名和端口号将客户端连接到TCP主机
BeginConnect
开始一个对远程主机连接的异步请求
EndConnect
异步接受传入的连接尝试
GetStream
获取能够发送和接收数据的NetworkStream对象
TCP编写服务器的步骤:
1.创建一个TcpListener对象,然后调用该对象的Start()方法在指定端口进行监听。
2.在单独的线程中,循环使用AcceptTcpClient()方法接受客户端的连接请求,在线程中与对应的客户进行通信。
3.每得到一个新的TcpClient对象,就创建一个与该客户对应的线程,在线程中与对应的客户进行通信。
4.根据传送信息的情况确定是否关闭与客户的连接。
TCP编写客户端的步骤:
1.利用TcpClient的构造函数创建一个TcpClient对象。
2.使用Connect()方法与服务器建立连接。
3.利用TcpClient对象的GetStream()方法得到网络流,然后利用该网络流与服务器进行数据传输。
4.创建一个线程监听指定的端口,循环接收并处理服务器发过来的信息。
5.完成工作后,向服务器发送关闭信息。
解决TCP的无消息边界问题:
1.发送固定长度的消息。
2.将消息长度与消息一起发送。
3.使用特殊标记分隔消息。(\r\n)
异步TCP应用编程:
异步编程两种模式:
1.基于事件的异步设计模式:用事件驱动模型实现异步方法,这种模式用单独的线程在后台执行耗时的任务,当后台任务完成时,就自动触发对应的事件。
2.基于IAsyncResult的异步设计模式:
1.基本原理:通过前缀分别为"Begin"和"End"的两个方法实现开始和结束异步操作。每个Begin方法必须都有个与其对应的End方法。
2.AsyncCallback委托:用于在异步操作完成时调用指定的回调方法。
TcpListener类、TcpClient类及Socket类提供的部分异步操作方法:
提供的方法
说明
TcpListener
BeginAcceptTcpClient
开始一个异步操作接受一个传入的连接尝试

EndAcceptTcpClient
异步接受传入的连接尝试,并创建新的TcpClient处理远程主机通信
TcpClient
BeginConnect
开始一个对远程主机连接的异步请求

EndConnect
异步接受传入的连接尝试
Socket
BeginReceive
开始从连接的Socket中异步接收数据

EndReceive
结束挂起的异步读取

BeginSend
将数据异步发送到连接的Socket

EndSend
结束挂起的异步发送

使用异步方式调用同步方法:

1.声明与要调用的方法具有相同签名的委托:

delegate void SendMessageDelegate(string message);

private void SendMessage(string message){

try{

bw.Write(message);

bw.Flush();

}catch{

MessageBox.Show("发送失败!");

}

}

2.通过轮询方法检查异步调用是否完成:

private bool needExit;

SendMessageDelegate d = new SendMessageDelegate(SendMessage);

IAsyncResult result = d.BeginInvoke(message,null,null);

while(result.IsCompleted == false)

{

if(needExit)

break;

Thread.Sleep(50);

}

3.使用EndInvoke结束异步调用:

private struct SendMessageStates{

public SendMessageDelegate d;

public IAsyncResult result;

}

private void AsyncSendMessage(string message)

{

SendMessageDelegate d = new SendMessageDelegate(SendMessage);

IAsyncResult result = d.BeginInvoke(message,null,null);

while(result.IsCompleted == false)

{

Thread.Sleep(50);

}

SendMessageStates states = new SendMessageStates();

states.d = d;

states.result = result;

Thread t = new Thread(FinishAsyncSendMessage);

t.IsBackground = true;

t.Start(states);

}

private void FinishAsyncSendMessage(object obj)

{

SendMessageStates states = (SendMessageStates)obj;

states.d.EndInvoke(states.result);

}

4.在异步调用中传递多个参数(参数可以使用out和ref关键字)

delegate void ReceiveMessageDelegate (out string receivemessage);

private void ReceiveMessage(out string receiveMessage){

receiveMessage = null;

try{

receiveMessage = br.ReadString();

}catch(Exception ex){

MessageBox.Show(ex.Message);

}

}

SendMessageDelegate d = new SendMessageDelegate(ReceiveMessage);

IAsyncResult result = d.BeginInvoke( out receiveMessage ,null,null);

while(result.IsCompleted == false){

Thread.Sleep(250);

}

d.EndInvoke(out receiveString,result);

C# | 阅读 3861 次
文章评论,共2条
司林林
2011-06-28 09:46
1
《数字技术与应用》8月份征稿。QQ:973530901
price
2011-07-28 14:13
2
谢谢了!!
游客请输入验证码