Socket的接收信息方法Receive的参数是一个byte[]数组,用在存放收到的数据。
byte[]是一个先要定义好的一个对象且具有大小,而收到的信息事先是不知道内容的大小,如果收到的内容的大小超出了byte[]的定义,超出的部分就会失去。
如何解决这个问题,让Receive的结果给一个可变的接收对象呢
我写的代码如下:
byte[] byteMessage=new byte[1000];
try
{
socket.Listen(5);
Socket newSocket=socket.Accept();
newSocket.Receive(byteMessage);
...
byte[]是一个先要定义好的一个对象且具有大小,而收到的信息事先是不知道内容的大小,如果收到的内容的大小超出了byte[]的定义,超出的部分就会失去。
如何解决这个问题,让Receive的结果给一个可变的接收对象呢
我写的代码如下:
byte[] byteMessage=new byte[1000];
try
{
socket.Listen(5);
Socket newSocket=socket.Accept();
newSocket.Receive(byteMessage);
...
解决方案 »
- 怎样把string转换回原来的font类型
- C#求纠错
- 各位高手!帮小弟一个GridView删除的忙!太急了!谢谢~50分!
- 找不到可安装的 ISAM. 很急啊
- 怎样实现像flashget那样拖动地址到浮动窗口就能被识别的功能?
- c#数组如何依次绑定到DropDownList
- 怎样通过CODE控制IIS的这个属性?
- 怎样把1,2,3,10显示为0001,0002,0003,0010啊?
- 请哪位把这句翻译成c#语句
- 用FinControl可以找到一个子控件,那么是否有类似的方法可以找到一个Component的子类实例?
- axWindowsMediaPlayer 控件如何实现连续播放多个
- C# 2005 里如何在datagridview中做chckbox是否被选中
{
.....
newSocket.Receive(byteMessage, BUFFERLENGTH,0);
.....}
常用的处理方式是 每次都去判断一下接收到的byteMessage, 如果有内容就继续执行Receive方法。这样循环就可以得到所有内容了。
-----------------------------------------------------
newSocket.Receive(byteMessage);
这个方法不是就一次性把信息给接下来了吗,怎么持续接收呢。能给代码吗
Header长度一般固定,我最近做了一个Socket通讯的,头长度24,用4个字节存储总长度;
你可以根据需要,在Header里预留几个字节存储总长度信息,
我取得时候先取24字节,然后再取出总长度;
然后根据总长度,去取Body,Body长度=总长度-Header长度;不知道我说清楚了么
_State.WorkSocket = _Client;
//获取头 HEADERSIZE市场量=24
byte[] _Header = new byte[HEADERSIZE];
byte[] _Body = null;
PackageHeader _PackageHeader = new PackageHeader();
int _BodyLength = 0;
string _ReceiveData = string.Empty;
_Client.Receive(_Header, HEADERSIZE, SocketFlags.None);
_PackageHeader = DecodeHeader(_Header);
//根据总长度得到包体长度
_BodyLength = int.Parse(_PackageHeader.Total_Length.ToString()) - HEADERSIZE;
if (_BodyLength > 0)
{
_Body = new byte[_BodyLength];
_Client.Receive(_Body, _BodyLength, SocketFlags.None);
_ReceiveData = Encoding.UTF8.GetString(_Header) + Encoding.UTF8.GetString(_Body);
}
不可能知道Recive长度的,除非你自己写的发送固定字段。
不用让byte[]数组大小随Socket的Receive接收的信息内容大小来变化。
因为可以让Socket的Receive方法不停的执行(即把它放入一个死循环里面)最后再判断一下Receive接收的数据量是否为0来作为停止循环的条件。
代码如下:
//得到指定Ip的IP的主机,即可以是外网的IP。通常都用外网的ip来通信
public static IPAddress GetServerIP(string LocalIP)
{
IPHostEntry ieh=Dns.GetHostByAddress(LocalIP);
return ieh.AddressList[0];
} private void BeginListen()
{
IPAddress ServerIp=GetServerIP(this.txtLocalIP.Text);
IPEndPoint iep=new IPEndPoint(ServerIp,int.Parse(txtPort.Text)); socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
this.label1.Text=iep.ToString(); socket.Bind(iep);
while(true)
{
try
{
string rmsg="";
socket.Listen(5);
Socket newSocket=socket.Accept();
int bytes=0;
while(true)
{
byte[] byteMessage=new byte[10];
//循环执行,它会从头到尾自动接收数据给存放对象。
//Receive的返回值是一个接收数据的字节数,必须得到该值,用以控制循环的次数和转换成字符串的字符数。
bytes=newSocket.Receive(byteMessage);
//或
//bytes=newSocket.Receive(byteMessage,byteMessage.Length,0); //控制循环次数
if(bytes<=0)
break;
//用Encoding.GetEncoding("gb2312"); 来写的话字符“@”就显示不正常
System.Text.Encoding encoding = System.Text.Encoding.UTF8;
string msg=encoding.GetString(byteMessage,0,bytes); //两种方式都可以,得到去除字符“\0”的有用字符串
//string msg=encoding.GetString(byteMessage).TrimEnd('\0'); //msg=msg.Split('\0')[0];
rmsg=rmsg+msg;
}
string sTime = DateTime.Now.ToShortTimeString();
rmsg=sTime+":"+"Message from:"+newSocket.RemoteEndPoint.ToString()+"\r\n"+rmsg+"\r\n"+"\r\n";
this.txtMessage.Text=this.txtMessage.Text+rmsg;
}
catch(SocketException ex)
{
this.label1.Text+=ex.ToString();
}
}
}
外面的while循环是让监听方法:BeginListen不停止,即一直监听下去,一般是用一个线程来执行。
里面的while循环是让Socket的Receive方法不停止接收信息。
定义的数组长度偏大