网络程序的问题(有点难,分不够可以加)(200分)

  • 主题发起人 主题发起人 jjweb
  • 开始时间 开始时间
J

jjweb

Unregistered / Unconfirmed
GUEST, unregistred user!
最近我在写一个网络程序,用TCP协议,在编写的过程中,遇到了这样的问题:
我看了很多网络程序,他们都是用socket.sendtxt和socket.ReceiveText来发送字符串信息
服务器端通过socket.Receivetext里开始的N个字符来确定请求的类别,然后读取后面的数据。
但我感觉这样不很好,我准备用socket.sendbuf和socket.Receivebuf来发送数据。
但服务器端怎么才可以区分客户端发送信息的类别呢?
例如:客户端有登陆,查询等操作,
在发送字符串的方式里,只要读取开头N个字符,如果是LOGIN就把后面的信息按照
登陆的数据结构读取,如果是FIND就把后面的信息按照查询来读取。
但在发送BUF的方式里,怎么做?
 
也是一样的啊~
其实字符串本质也可以说成是BUFFER啊
 
to 天真
能说的详细点吗?我很苯
 
可以先用ReceiveBuf先读到Buffer中,然后判断前面的字符,再决定按什么方式读Buffer后面的数据.
 
在说的详细点:
如果发送的数据结构有
type mr1=recore
code:string[6];
am:string[5];
end;
type mr2=recore
code:string[6];
price:integer;
end;
我在接收的时候,怎么才可以区分发送过来的数据是什么结构呢?
如果需要在两个结构之前加上个头,但怎么去读取这个头 ?
 
to szf
你说:
可以先用ReceiveBuf先读到Buffer中,然后判断前面的字符,
再决定按什么方式读Buffer后面的数据

但是,因为发送的数据的结构是不一样的,你说先读到BUFFER中,这个BUFFER的结构是什么样的呢?
 
这个BUFFER可以是一个结构体呀!
 
to 张无忌
buffer是一个结构,
但客户端发送的时候,结构会有多种,服务端接收的时候,怎么区分是怎么结构呢?
 
我的QQ是1752440
email:jjweb@21cn.com
希望大家能指导我一下,我愿意给300分
 
你的服务器可以做成状态控制的,到了什么状态就用什么结构的结构去读,如果
参数不对就关闭套接字
 
sendtext和sendBuffer实质上并没有什么区别。String也可以做成Buffer,你想得太复杂了。
 
我认为上面说的方法都不太,我做程序一般都是这个做的:

服务端一个serversocket,客户端2个clientsocket,一个用sendtext来发命令,一个用sendbuffer来发文件
之类的,速度快且可同时进行发送和接收,还很好实现处理命令队列
 
在buffer前面加一个鉴别字符,1 =XX类型,2=YY类型......
用Case判断,然后写到结构类型的变量里去。
 
赞成无忌兄的方法,我曾经就是用的这种方法实现的
 
buffer就是一块内存区啦!根据数据量分配一块内存,不管什么结构读进去先。
然后取出前6个字节,得到它是什么结构的,然后强制类型转换到该结构的指针
不就好了
 
如果实现不行就用枚举吧
TTest = record
i : integer;
case integer of
0 : (Format : TWaveFormatEx);
1 : (RawData : Array[0..128] of byte);
end;

首先,你去读I,如果I等于0,你就可以读FORMAT了,如果I等于1你就可以读RAWDATA,
以此类推吧
 
type //建议修改结构如下
mr1=record
am: array[0..4] of Char //因为String类型的变量的第一个byte是用来保存长度的
end; //所以如果是定长字串,用字符数组来实现比较好些
pMR1 = ^mr1;

mr2=record
price:integer;
end;
pMR2 = ^mr2;

procedure TForm1.Button1Click(Sender: TObject);
var CodeBuf: String;
TmpBuf: array of Byte;
pBuf: Pointer;
DescString: String;
DescInteger: Integer;
begin
SetLength(CodeBuf, 6);
ClientSocket1.Socket.ReceiveBuf(CodeBuf[1],6);//读前6个字符
//调试用 CodeBuf := 'aaaaaa';
SetLength(TmpBuf, 256);
pBuf := @TmpBuf[0]; //取得缓冲区起始指针位置
ClientSocket1.Socket.ReceiveBuf(TmpBuf,256);
//调试用 TmpBuf[0] := 65; TmpBuf[1]:=66; TmpBuf[2] := 68;
if CodeBuf='aaaaaa' then
begin
DescString := StrPas(pMR1(pBuf)^.am); //强制指针类型转换
ShowMessage(DescString);
end
else if CodeBuf='bbbbbb' then
begin
DescInteger := pMR2(pBuf)^.price; //强制指针类型转换
ShowMessage(IntToStr(DescInteger));
end;
end;
说明:如果前6个字符是aaaaaa的话,那么它就是结构1的数据
如果前6个字符是bbbbbb的话,那么它就是结构2的数据
限制:
1、一个结构的数据量不能超过256个
2、一个结构体中不能包含变长的数据(但我个人认为这个不是个问题)
 
多人接受答案了。
 
后退
顶部