网络编程概述(二)
1.线程基础知识 star().abort().sleep().Suspend().Resume().
2.读取数据时判断是否接受数据大于0,注意设置缓冲区大小,读取有效的缓冲区(0-总长度,读取完一次后重新计数
3.TCP是面向流的,是无边界保护的消息模式,不管发送方发多少流,在接收端可能一次性全部接收完流。要解决这个问题有3种方法:
第一:接收定长的字节流
private byte[] ReciveMessage(Socket s, int size)
{
int offset = 0;
int recv;
int dataleft = size;
byte[] msg = new byte[size];
while (dataleft > 0)
{
//接收消息
recv = s.Receive(msg, offset, dataleft, 0);
if (recv == 0)
{
break;
}
offset += recv;
dataleft -= recv;
}
return msg;
}
以上这种做法比较适合于消息长度不是很长的情况
第二:可以把需要发送消息内容大小在发送消息之前发送给接收端,接收端在根据发送内容大小定义缓冲区接收数据。
private static int SendMessage(Socket s, byte[] msg)
{
int offset = 0;
int sent;
int size = msg.Length;
int dataleft = size;
byte[] msgsize = new byte[2];
//将消息尺寸从整形转换成可以发送的字节型
msgsize = BitConverter.GetBytes(size);
//发送消息的长度信息
sent = s.Send(size);
while (dataleft > 0)
{
sent = s.Send(msg, offset, dataleft, SocketFlags.None);
//设置偏移量
offset += sent;
dataleft -= sent;
}
return offset;
}
下面是接收变长消息的ReciveVarMessage方法。代码如下:
private byte[] ReciveVarMessage(Socket s)
{
int offset = 0;
int recv;
byte[] msgsize = new byte[2];
//接收2个字节大小的长度信息
recv = s.Receive(msgsize, 0, 2, 0);
//将字节数组的消息长度信息转换为整形
int size = BitConverter.ToInt16(msgsize);
int dataleft = size;
byte[] msg = new byte[size];
while (dataleft > 0)
{
//接收数据
recv = s.Receive(msg, offset, dataleft, 0);
if (recv == 0)
{
break;
}
offset += recv;
dataleft -= recv;
}
return msg;
}
第三:使用特殊标记来区分消息间隔, 该方案使用预先确定的一个字符(或多个字符)来指定消息的结束,通过这种方式来分隔不同的消息。但用这种方法必须对所接收到的每一个字符进行检查以便确定为结束标记,这对于大型消息来说,可能导致系统性能的下降,不过对于C#语言来说,提供了一些类,能够用于简化这个过程,那就是System.IO命名空间流类,下面我们也着重来讲一下这各方法。

浙公网安备 33010602011771号