混合byte[]如何解析出来?就是byte[]里写入了int,string等

andytang555 2008-12-10 07:54:01
写入端socket.send(Encoding.UTF8.GetBytes("dfdff\0");接收对应用的GetString能正确解析出来,加入Int后为什么解析不出来了呢?
写入端:
byte[] bta1 = BitConverter.GetBytes(1001);
byte[] bta2 = BitConverter.GetBytes(0);
byte[] bta = Encoding.UTF8.GetBytes("dfdfdfdf\0");
socket.send(ByteConnector.concat(bta1,bta2,bta);
接收端:
ByteArray bta = new ByteArray(receivedByte);
int test1 = bta.ReadInt();
int test2 = bta.ReadInt();
int test3 = bta.ReadUTF();其中ByteConnector和ByteArray是自己写的类,我也怀疑这类有问题,就不上类代码了,帮助大家理解我的意图就是了,怎么解决?谢谢大家先!
...全文
245 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
mykelly6 2008-12-11
  • 打赏
  • 举报
回复
知道结构是不是可以按byte来读阿,数字就按原样,string就encoding转化一下~
wjq 2008-12-11
  • 打赏
  • 举报
回复
/// <summary>
/// 快速复制内存,可用于强行的类型转换,必须非安全(unsafe{})块中使用,非必要,不建议使用。
/// </summary>
/// <param name="Destination">目标对象的指针</param>
/// <param name="Source">源对象的指针</param>
/// <param name="Length">要复制的长度(单位:字节)</param>
[DllImport("kernel32.dll", CharSet = CharSet.Auto, EntryPoint = "RtlMoveMemory", CallingConvention = CallingConvention.StdCall)]
public static unsafe extern void CopyMemory(void* Destination, void* Source, int Length);
zgke 2008-12-11
  • 打赏
  • 举报
回复
你的根据你的 ByteConnector来按BYTE读数据~~
journeydj 2008-12-11
  • 打赏
  • 举报
回复
业务上一定要分清数值和字符串吗? 那恐怕不好办。
全转成string再传。
zhyuanshan 2008-12-11
  • 打赏
  • 举报
回复
数字必须知道它存放的位置和类型,string必须知道它存放的位置和长度
这样才可以解析出来
烈火蜓蜻 2008-12-10
  • 打赏
  • 举报
回复
数字先发送,到接收端,先行把头几个字节截取,然后把余下再组成字符 串
andytang555 2008-12-10
  • 打赏
  • 举报
回复
还用到一个类:AsyncSocket

//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥代理类型
public delegate void StreamReceiveHandler(string newId, Socket socket, byte[] data);
public delegate void StringReceiveHandler(string newId, Socket socket, string str);
public delegate void SocketSendedHandler(string sendId, string message);
public delegate void SocketAcceptHandler(AsyncSocket newSocket);
public delegate void SocketClosedHandler(string socketId, string message);
public delegate void SocketListenedHandler(AsyncSocket socket, string message);
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥
public class AsyncSocket
{
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥事件变量
private StreamReceiveHandler onStreamData = null;
private StringReceiveHandler onStringData = null;
private SocketSendedHandler onSended = null;
private SocketSendedHandler onCasted = null;
private SocketAcceptHandler onAccept = null;
private SocketClosedHandler onClosed = null;
private SocketListenedHandler onListened = null;
private SocketListenedHandler onListenFailed = null;
private IPEndPoint m_obEndPoint;
private string m_stId = "";
private Socket m_socket = null;

#region 构造函数
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥构造函数
public AsyncSocket (AddressFamily af, SocketType st , ProtocolType pt){
m_socket = new Socket(af, st, pt);
}
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥重构函数
public AsyncSocket(Socket socket)
{
m_socket = socket;
m_stId = Guid.NewGuid().ToString();
}
#endregion

#region 回调函数
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥数据接收回调
private void ReceiveCallback(IAsyncResult ar)
{
try
{
//
SocketStateObject state = ar.AsyncState as SocketStateObject;
//读取数据
int bytesRead = m_socket.EndReceive(ar);
if (bytesRead > 0)
{
state.tempString.Append(UTF8Encoding.UTF8.GetString(state.buffer, 0, bytesRead));
string str = state.tempString.ToString();
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥
if (str.Substring(str.Length - 1, 1) == "\0")
{
//接收完成
//激发事件
if (onStreamData != null)
onStreamData(m_stId, m_socket,UTF8Encoding.UTF8.GetBytes(str));
if (onStringData != null)
onStringData(m_stId, m_socket,str);
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥一轮接收完毕必须重设状态
state = new SocketStateObject(m_socket);
}
// Get the rest of the data.
m_socket.BeginReceive(state.buffer, 0,
SocketStateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
}
catch (SocketException se)
{
if (onClosed != null)
onClosed(ID, se.Message);
}
catch (Exception e)
{
MessageBox.Show(e.Message.ToString());
}

}
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥连接接受回调
private void AcceptCallBack(IAsyncResult ar)
{
Socket handler = m_socket.EndAccept(ar);
AsyncSocket newSocket = new AsyncSocket(handler);
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥激发事件
if (null != onAccept)
{
onAccept(newSocket);
}
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥重新监听
m_socket.BeginAccept(new AsyncCallback(AcceptCallBack), null);
}
#endregion

andytang555 2008-12-10
  • 打赏
  • 举报
回复
不好意思忘改了,Console.writeLine(data.readInt().toString());//就这一句读出来的值不对
Console.writeLine(data.readUTF());
应为:
Console.writeLine(bta.readInt().toString());//就这一句读出来的值不对
Console.writeLine(bta.readUTF());
ByteArray类(自己写的,很可能有问题):

private const int Blength32 = 4;
private int m_intPos = 0;
private byte[] m_obTarget;
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥构造函数
public ByteArray(byte[] target)
{
m_obTarget = target;
}
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥
public int ReadInt()
{
byte[] bta = new byte[Blength32] { 0, 0, 0, 0 };
for (uint i = 0; i < 4; i++)
{

bta[i] = m_obTarget[m_intPos + i];
}
m_intPos += Blength32;
return BitConverter.ToInt32(bta,0);
}
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥
public string ReadUtf()
{
int length = this.ReadInt();
string str = Encoding.UTF8.GetString(m_obTarget, m_intPos, length);
m_intPos += length;
return str;
}

andytang555 2008-12-10
  • 打赏
  • 举报
回复
哎,为什么没有一个人明白我的问题呢
我知道根据字节内容不可能判断出是int还是string,我的问题就是知道字节结构我也取不出来,我刚从as3转到c#,不太懂,比如客户端writeInt,然后writeUTF,服务端知道这个结构,怎么把int和string取出来,我上代码吧,客户端代码就省了
服务端:

public partial class Form1 : Form
{
private int m_backLogLength = 10 ;
private AsyncSocket m_obSocket;
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥startOk
void m_obSocket_OnListened(AsyncSocket socket, string message)
{
Console.writeLine( "startOk" );
m_obSocket.OnAccept += new SocketAcceptHandler(m_obSocket_OnAccept);
}
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥accept
void m_obSocket_OnAccept(AsyncSocket newSocket)
{
newSocket.OnStreamReceived += new StreamReceiveHandler(newSocket_OnStreamReceived);
}
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥dataReceive
void newSocket_OnStreamReceived(string newId, Socket socket, byte[] data)
{
ByteArray bta = new ByteArray(data);//ByteArray类代码见下面
Console.writeLine(data.readInt().toString());//就这一句读出来的值不对
Console.writeLine(data.readUTF());
}
//∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥∥formLoad
private void Form1_Load(object sender, EventArgs e)
{

m_obSocket = new AsyncSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//
m_obSocket.OnListened += new SocketListenedHandler(m_obSocket_OnListened);
m_obSocket.OnListenFailed += new SocketListenedHandler(m_obSocket_OnListenFailed);
//
m_obSocket.Start("127.0.0.1", 1109, m_backLogLength);
}
特别 2008-12-10
  • 打赏
  • 举报
回复
要不然就是固定格式的,例如1-3字节为int型,4-8字节为string型,等等,直接根据byte是无法判断存储哪种类型的,因为所有信息都是以byte存储、传输的,
再不然就是上面说的加特殊标志
长沙三毛 2008-12-10
  • 打赏
  • 举报
回复
个人认为,虽然混合在一起节省空间,但处理和维护不容易,因为还要考虑著名的“粘包”问题、传输发生错误等问题。因此,这种设计需要改进,同意1楼的观点。
设计与编写程序,不是技巧上取胜,而是方法和思路为王。
andytang555 2008-12-10
  • 打赏
  • 举报
回复
楼上没有明白我的问题,我的问题是写进去的和读出来的不对等,不是转换,单独转换我会,单独传输也没问题,问题是怎么把bta1,bta2,bta连接起来并通过socket发送出去,再解析出来就出问题了.
就是用socket传输和解析string没问题,传输混合类型不会
王集鹄 2008-12-10
  • 打赏
  • 举报
回复
byte[] bta1 = BitConverter.GetBytes(1001);
byte[] bta2 = BitConverter.GetBytes(0);
byte[] bta = Encoding.UTF8.GetBytes("dfdfdfdf\0");
Console.WriteLine(BitConverter.ToInt32(bta1, 0));
Console.WriteLine(BitConverter.ToInt32(bta2, 0));
Console.WriteLine(Encoding.UTF8.GetString(bta));
andytang555 2008-12-10
  • 打赏
  • 举报
回复
不是吧,不可以直接判断?我以前专写flash的,只会发送,发送的时候也没加什么标志啊??那我们公司的后台人员怎么读出来的?
GTX280 2008-12-10
  • 打赏
  • 举报
回复
没办法判断哪些字节是字符哪些是int数值吧。
可以考虑加上两个特殊的值作标记,一个指示后面的字节是字符,一个指示为数值

111,130

社区成员

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

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

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