请教各位高手一个SOCKET的问题

xijhee 2002-05-29 03:12:29
请教各位高手一个SOCKET的问题

CLIENT和SERVER采用TCP方式连接。每帧1000字节。
SERVER每接收一帧就先保存一条记录。

在运行时有以下的问题

在发送方请看LOG记录:
MB1表示第一条记录
...
MB4表示第四条记录
(1000)表示发送的字节数,我发送的数组已定义为 A[1000]
---------------------------
1999-3-3 14:37:14 发送加卡数据:MB1:99,001,00002,99,50,2002-5-15,00000002
1999-3-3 14:37:14 14:37:14 已发送数据(OK)!->Send()(1000)
1999-3-3 14:37:14 14:37:14... ... ...
1999-3-3 14:37:14 发送加卡数据:MB2:99,001,00001,99,50,2002-5-15,00000001
1999-3-3 14:37:14 14:37:14 已发送数据(OK)!->Send()(1000)
1999-3-3 14:37:14 14:37:14... ... ...
1999-3-3 14:37:14 发送加卡数据:MB3:99,001,00001,100,50,2002-5-16,00000001
1999-3-3 14:37:14 14:37:14 已发送数据(OK)!->Send()(1000)
1999-3-3 14:37:14 14:37:14... ... ...
1999-3-3 14:37:14 发送加卡数据:MB4:99,001,00001,100,50,2002-5-16,00000001
1999-3-3 14:37:14 14:37:14 已发送数据(OK)!->Send()(1000)
---------------------------


在接受方请看LOG记录
MB1表示第一条记录
...
MB4表示第四条记录
(1000)表示接受的字节数,我接受的数组已定义为 A[1000]
--------------------
1999-3-3 14:37:19 14:37:19 RECV收到数据:MB1:99,001,00002,99,50,2002-5-15,00000002(1000)
1999-3-3 14:37:20 14:37:20 RECV收到数据:MB2:99,001,00001,99,50,2002-5-15,00000001 (460) <-(注:只接收了460字节)
1999-3-3 14:37:20 14:37:20 RECV收到数据:MB3:99,001,00001,100,50,2002-5-16,00000001(1000)
1999-3-3 14:37:20 14:37:20 RECV收到数据:(540) <-(注:一行空的,接受了540字节)
1999-3-3 14:37:20 14:37:20 RECV收到数据:MB4:99,001,00001,100,50,2002-5-16,00000001(1000)
-------------------
刚好(460)+(540)=(1000)

请问为什么会发生这样的问题和有什么方法解决?请教,请教!
...全文
27 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
rebnik 2002-05-29
  • 打赏
  • 举报
回复
流套接字是一个不间断的数据流,应用程序在读取它时,和它应该读多少数据之间通常没有关系。如果应用程序需要依赖于流协议的离散数据,你就就有别的事要做。如果所有消息长度都一样,则比较简单,也就是说,512个字节的消息看起来就象下面这样:

char recvbuff[1024];
int ret, nLeft, idx;

nLeft = 512;
idx = 0;

while(nLeft > 0)
{
ret = recv(s, &recvbuff[idx], nLeft, 0);
if (rt == SOCKET_ERROR)
{
// Error
}
idx += ret;
nLeft -= ret;
}

希望对你有帮助。
rebnik 2002-05-29
  • 打赏
  • 举报
回复
流套接字是一个不间断的数据流,应用程序在读取它时,和它应该读多少数据之间通常没有关系。如果应用程序需要依赖于流协议的离散数据,你就就有别的事要做。如果所有消息长度都一样,则比较简单,也就是说,512个字节的消息看起来就象下面这样:

char recvbuff[1024];
int ret, nLeft, idx;

nLeft = 512;
idx = 0;

while(nLeft > 0)
{
ret = recv(s, &recvbuff[idx], nLeft, 0);
if (rt == SOCKET_ERROR)
{
// Error
}
idx += ret;
nLeft -= ret;
}

希望对你有帮助。
xijhee 2002-05-29
  • 打赏
  • 举报
回复
请问接受控制部分的方法是怎样的?
MSVCer 2002-05-29
  • 打赏
  • 举报
回复
同意 westwf()
xijhee 2002-05-29
  • 打赏
  • 举报
回复
请教...
procedure TRecvThread.Execute;
begin
try
while not self.Terminated do ServerFrm.PServerRecv(self.ActiveSocket);
except
end;
end;

procedure TServerFrm.PServerRecv(ActiveS:TSocket);
begin
try
self.PSetByteBufferZero(BlockBuf,BlockLen);
ReceLen:=recv(Actives,BlockBuf,BlockLen,0);
if ReceLen>=0 Then
begin
if ReceLen=0 then
begin
self.PGotoListen;
exit
end;

self.PByteToString(BlockBuf,BlockLen,TempStr);
self.PShowMsg(timetostr(time)+' 收到数据:'+tempstr+'('+inttostr(ReceLen)+')');

if (Copy(Trim(TempStr),1,4)='MB') and self.PServerActive then
begin
if (Copy(Trim(TempStr),5,2)='1:') then
begin
if not adocon1.InTransaction then
adocon1.BeginTrans
else
begin
adocon1.RollbackTrans;
adocon1.BeginTrans;
end;
end;
self.PSaveAddMDataSend(ActiveS,TempStr);
end;

end;
except
end;
end;
不解 2002-05-29
  • 打赏
  • 举报
回复
接受控制的问题,贴出你的接受部分看看。
xuying 2002-05-29
  • 打赏
  • 举报
回复
TCP是流式的数据传输,发送方发一次,接收方未必一次就接受完全,可能需要多次。只有UDP是数据报方式的,一次发送对应一次接收。

你必须按字节来判断是否接收完全,不能认为一次recv就可以接收发送方发送的1000字节。
westwf 2002-05-29
  • 打赏
  • 举报
回复
可能是你的接收发程序没有判断一个数据包完整性的措施:
你可以约定一个报头,开始部分四个字节声明这次发送的字节数,比如是1000个字节,接受方接到数据包后应当先看看报头这次发送的字节数是多少,然后再循环调用recv直到所有的字节数接收完,才认为这次的数据报(比如你那1000个字节)全部收到了,而并不是你调用一次recv就一定可以收到所有的1000个数据(和网络有关,有时网络很堵塞的话一次可以收到的字节就少)。

4,356

社区成员

发帖
与我相关
我的任务
社区描述
通信技术相关讨论
社区管理员
  • 网络通信
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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