udp数据包做标记出了问题-----巨大的问题

lucbesson 2005-04-13 07:46:09
///SERVER发送做了标记的数据
private void Send()
{
IPAddress ip = IPAddress.Parse("192.168.1.255");
int port = 11000;

UdpClient sender = new UdpClient();
IPEndPoint ipep = new IPEndPoint(ip, port);

try
{
string str=this.rtxtSendMsg.Text ;

byte[] bytes =Encoding.Unicode.GetBytes(str);

//总包的大小
int totalSize=bytes.Length;
//如果总包小于1024做个标记并发送
if(totalSize<1024)
{ //数据小于1024字节,进行标记,方便Client接收
byte[] b1=new byte[totalSize+1];
b1[0]=1;
Array.Copy(bytes,0,b1,2,totalSize);
sender.Send(b1,b1.Length);
}
else
{
MessageBox.Show ("sorry");
}

}

///CLIENT接收数据
private void Listen()
{
int port = 11000;

UdpClient listener = new UdpClient(port);
RemoteIpEndPoint=null;


while(true)
{
try
{
byte[] receiveBytes=listener.Receive(ref RemoteIpEndPoint);
//数据小于1024字节的,处理掉标记后进行输出
if(receiveBytes[0]==1)
{
//长度减1
byte[] b1=new byte[receiveBytes.Length-1];
//除去标记 装如字节数组b1
Array.Copy(receiveBytes,2,b1,0,receiveBytes.Length-1);
string returnData=Encoding.Unicode.GetString(b1,0,b1.Length);
this.rtxtHistory.Text=returnData;
}
else
{
MessageBox.Show("转换出错了");
}


}
catch (System.Exception pe)
{
Console.WriteLine(pe.ToString());
}
}


问题: 接收端没有效果,在做标记和出去标记上一定有错误,请朋友帮我修改一下代码。
谢谢
...全文
181 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
lucbesson 2005-04-14
  • 打赏
  • 举报
回复
byte[] b1=new byte[totalSize+4];
//把标记转换成byte
b1[0]=byte.Parse(1.ToString(),System.Globalization.NumberStyles.AllowCurrencySymbol);

可这里我是把标记打在了前四个字节中了啊
lucbesson 2005-04-14
  • 打赏
  • 举报
回复
修改成 bool Flag=Array.Equals(Abyte,Bbyte); 还是不对 。

server我是这样给数据报做标记的

udp.Connect(endpoint);
string str=this.richTextBox1.Text ;
byte[] bytes =Encoding.Unicode.GetBytes(str);
//总包的大小
int totalSize=bytes.Length;
//如果总包超过udp的最大传输自己即MTU,则进行分包
if(totalSize<1024)
{ //数据小于1024字节,进行标记,方便Client接收
byte[] b1=new byte[totalSize+4];
//把标记转换成byte
b1[0]=byte.Parse(1.ToString(),System.Globalization.NumberStyles.AllowCurrencySymbol);
//把总的richtextbox中的数据拷贝到b1数组中,注意下标 totalsize
Array.Copy(bytes,0,b1,4,totalSize);
udp.Send(b1,b1.Length);
}
else
{
MessageBox.Show ("sorry");
}
wangsaokui 2005-04-14
  • 打赏
  • 举报
回复
bool Flag=Array.Equals(Abyte,Bbyte);

一般来讲,网络传输会把数据包长度写到包头的前两个或前4个字节,你取的时候先判断下包的长度(length属性)和包头的长度信息是否相等就可以了,
lucbesson 2005-04-14
  • 打赏
  • 举报
回复
感谢各位朋友,测试成功

谢谢

特别感谢cnming(cnming) ,谢谢你给了我很多的帮助。

结帖
lucbesson 2005-04-14
  • 打赏
  • 举报
回复
测试的结果是:
这样没有任何内容显示在CLIENT 端
private void Receive()
{


// **STEP 1**
receive= new UdpClient(port);
while(true)
{
RemoteIpEndPoint=null;
try
{

// **STEP 2** receiving the data
byte[] receiveBytes=receive.Receive(ref RemoteIpEndPoint);
//取出receiveBytes数组的前四个数据
byte[] Abyte=new byte[4];
Array.Copy(receiveBytes,0,Abyte,0,4);
//把数字1的byte数据装到数组中去
byte[] Bbyte=new byte[4];
Bbyte[0]=byte.Parse(1.ToString(),System.Globalization.NumberStyles.AllowCurrencySymbol);
//比较两个数组
bool Flag=Array.Equals(Abyte,Bbyte);
//数据小于1024字节的,处理掉标记后进行输出
//对标记进行校验
if(Flag)
{
//长度减4
byte[] b=new byte[receiveBytes.Length-4];
//除去标记 从receiveBytes的第四个字节开始拷贝字节长度为receiveBytes.Length-4
Array.Copy(receiveBytes,4,b,0,receiveBytes.Length-4);
string returnData=Encoding.Unicode.GetString(b,0,b.Length);
this.richTextBox1.Text=returnData;
}
else{}
catch(Exception e)
{
MessageBox.Show(e.ToString());
}
}

如果这样:
private void Receive()
{


// **STEP 1**
receive= new UdpClient(port);
while(true)
{
RemoteIpEndPoint=null;
try
{

// **STEP 2** receiving the data
byte[] receiveBytes=receive.Receive(ref RemoteIpEndPoint);
//长度减4
byte[] b=new byte[receiveBytes.Length-4];
//除去标记 从receiveBytes的第四个字节开始拷贝字节长度为receiveBytes.Length-4
Array.Copy(receiveBytes,4,b,0,receiveBytes.Length-4);
string returnData=Encoding.Unicode.GetString(b,0,b.Length);
this.richTextBox1.Text=returnData;
}
catch(Exception e)
{
MessageBox.Show(e.ToString());
}
}
则可以正确的显示出SERVER发送的数据。
问题就出现在:从byte[] receiveBytes=receive.Receive(ref RemoteIpEndPoint);中取出的标记,并比较数组进行校验比较那一段上,
byte[] receiveBytes=receive.Receive(ref RemoteIpEndPoint);
//取出receiveBytes数组的前四个数据
byte[] Abyte=new byte[4];
Array.Copy(receiveBytes,0,Abyte,0,4);
//把数字1的byte数据装到数组中去
byte[] Bbyte=new byte[4];
Bbyte[0]=byte.Parse(1.ToString(),System.Globalization.NumberStyles.AllowCurrencySymbol);
//比较两个数组
bool Flag=Object.Equals(Abyte,Bbyte);
//数据小于1024字节的,处理掉标记后进行输出
//对标记进行校验
if(Flag)
{ ////:todo }

TonyTonyQ 2005-04-14
  • 打赏
  • 举报
回复
byte[] b1=new byte[totalSize+1];
b1[0]=1;
Array.Copy(bytes,0,b1,2,totalSize);
==>
byte[] b1=new byte[totalSize+1];
b1[0]=1;
Array.Copy(bytes,0,b1,1,totalSize); ***

或者

byte[] b1=new byte[totalSize+1];
b1[0]=1;
Array.Copy(bytes,0,b1,2,totalSize);
==>
byte[] b1=new byte[totalSize+2]; ***
b1[0]=1;
Array.Copy(bytes,0,b1,2,totalSize);

注***的为修改语句,接受的时候按照发送的标记规则也要做相应修改。
jimh 2005-04-14
  • 打赏
  • 举报
回复
//数据小于1024字节,进行标记,方便Client接收
byte[] b1=new byte[totalSize+1];
b1[0]=1;
Array.Copy(bytes,0,b1,2,totalSize);
//这里出错了,应改为 Array.Copy(bytes,0,b1,1,totalSize);


//长度减1
byte[] b1=new byte[receiveBytes.Length-1];
//除去标记 装如字节数组b1
Array.Copy(receiveBytes,2,b1,0,receiveBytes.Length-1);
//同样,这里也错了,应改为Array.Copy(receiveBytes,1,b1,0,receiveBytes.Length-1);

cnming 2005-04-14
  • 打赏
  • 举报
回复
获取byte数组

string m_strTmp = "fsfsafs";
ClassData CD = new ClassData();
CD.m_intSN = 1;
CD.m_intDataLength = m_strTmp.Length;
CD.m_strData = m_strTmp;
byte[] data = CD.GetBytes();



还原

byte[] data = server.Receive(ref sender);
ClassData CD = new ClassData(data);
string m_strTmp = CD.m_strData;
int m_intLength = CD.m_intDataLength;
int m_intSN = CD.m_intSN;
cnming 2005-04-14
  • 打赏
  • 举报
回复
你按照我的上一个贴给你的代码建立一个class,然后直接调用不就可以了?


using System;
using System.Text;

namespace UDPTest
{
/// <summary>
/// ClassEmployee 的摘要说明。
/// </summary>
public class ClassData
{
public int m_intSN; //数据戳功能
public int m_intDataLength; //数据长度
public string m_strData; //数据内容

public ClassData()
{
}

//还原数据
public ClassData(byte[] data)
{
int place = 0;
m_intSN = BitConverter.ToInt32(data,place);
place += 4;
m_intDataLength = BitConverter.ToInt32(data,place);
place += 4;
m_strData = Encoding.ASCII.GetString(data,place,m_intDataLength);
}

//转换数据为字节数据
public byte[] GetBytes()
{
byte[] data = new byte[1024];
int place = 0;
Buffer.BlockCopy(BitConverter.GetBytes(m_intSN), 0, data,place,4);
place += 4;
Buffer.BlockCopy(BitConverter.GetBytes(m_intDataLength), 0, data,place,4);
place += 4;
Buffer.BlockCopy(Encoding.ASCII.GetBytes(m_strData), 0, data,place,m_strData.Length);
return data;
}

}
}

lucbesson 2005-04-13
  • 打赏
  • 举报
回复
新问题 :
byte[] receiveBytes=receive.Receive(ref RemoteIpEndPoint);
//取出receiveBytes数组的前四个数据
byte[] Abyte=new byte[4];
Array.Copy(receiveBytes,0,Abyte,0,4);
//把数字1的byte数据装到数组中去
byte[] Bbyte=new byte[4];
Bbyte[0]=byte.Parse(1.ToString(),System.Globalization.NumberStyles.AllowCurrencySymbol);
//比较两个数组
bool Flag=Object.Equals(Abyte,Bbyte);
//数据小于1024字节的,处理掉标记后进行输出
//对标记进行校验
if(Flag)
{
//长度减4
byte[] b=new byte[receiveBytes.Length-4];
//除去标记
Array.Copy(receiveBytes,4,b,0,receiveBytes.Length-4);
string returnData=Encoding.Unicode.GetString(b,0,b.Length);
this.richTextBox1.Text=returnData;
}
else{}

-----------------------------------------------
问题在这里 比较两个数组相等 这样对吗 ?
//比较两个数组
bool Flag=Object.Equals(Abyte,Bbyte);
lucbesson 2005-04-13
  • 打赏
  • 举报
回复
楼上的朋友 你说的不对,不是sender.Send(b1,b1.Length,ipep);的问题 。
sunkangta 2005-04-13
  • 打赏
  • 举报
回复
sender.Send(b1,b1.Length,ipep);
lucbesson 2005-04-13
  • 打赏
  • 举报
回复
只是为了练习一下如何把数据包加标记,接受的时候去掉标记。
lucbesson 2005-04-13
  • 打赏
  • 举报
回复
有可能在数据移动的时候出了点问题

可是我实在是找不出来啦 。

气。。。

110,532

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧