急在线等,重叠I/O模型,发送数据包中存在#0,#0以后的内容服务器端无法收到. ( 积分: 200 )

  • 主题发起人 主题发起人 sjg23690428
  • 开始时间 开始时间
S

sjg23690428

Unregistered / Unconfirmed
GUEST, unregistred user!
我最出写的那个消息模型没有这个问题,这次用的是重叠I/O,当用WSARecv接数据时出些问题
例如:我发送‘AAAAAAA#0BBBBB’后边的BBBBB都收到不到了。
Sock_Error:= WSARecv(USEDataPool.PutItems(idposition).SockSign ,
@USEDataPool.GetItems[idposition].DataBuf,1,
USEDataPool.GetItems[idposition].dwRecvBytes,
USEDataPool.GetItems[idposition].Flags,
@USEDataPool.GetItems[idposition].AcceptOverlapped, nil);

‘USEDataPool.GetItems[idposition].dwRecvBytes’这个值为12,
但USEDataPool.GetItems[idposition].DataBuf.buf 这个变量中是‘AAAAAAA’
大家说这是怎么回事
 
这样肯定会丢的,你必须转码一下才行!
 
to:xzmyzy 可是我发的文件中有#0啊
 
正常,DataBuf是PChar类型,PChar在调试状态,不会看到#0后面的数据,但,内容还是存在的

眼睛看到的,又不一定是真的,你print出来不就完了
 
发送方:定义类型
isendbuf,iitmpbuf : array[0..DATA_BUFSIZE] of char;
itmpbuf : array[0..DATA_BUFSIZE] of char;
IDataBuf : array[0..DATA_BUFSIZE] of char;

ifilebuf := Tfilestream.Create(FfileFPath, fmopenread);
try
ifilebuf.position := 0;
if Gauge<>nil then
begin
Gauge.Progress:=0;
Gauge.MaxValue:= ifilebuf.Size;
end;
repeat
// ZeroMemory(@itmpbuf,DATA_BUFSIZE);
icount := ifilebuf.Read(itmpbuf, 2000);
ilen:=icount+8;
isumsend:=ilen;
if icount <= 0 then
begin
tmpstr := FHE + format('%.4d', [ilen]);
end
else
begin
tmpstr := FHN + format('%.4d', [ilen]);
end;
ZeroMemory(@isendbuf,DATA_BUFSIZE);
// Fullchar(isendbuf, tmpstr);
for i := 0 to icount - 1 do
begin
isendbuf[i + 8] := itmpbuf;
end;
ZeroMemory(@iitmpbuf,DATA_BUFSIZE);
for i := 0 to ilen-1 do
begin
iitmpbuf := isendbuf;
end;
fd_zero(iwriteset);
fd_set(FCsocket, iwriteset);
tv.tv_sec := FoverTime;
tv.tv_usec := 0;
icount:=0;
while icount<isumsend do
begin
iret := select(FCsocket, nil, @iwriteset, nil, @tv);
if (iret = socket_error) or (iret = 0) then
begin
Conn:= false;
ifilebuf.Free;
Result := false;
exit;
end;
if fd_isset(FCsocket, iwriteset) then
begin
iret := send(FCsocket, isendbuf, ilen, 0);
if (iret = socket_error) or (iret = 0) then
begin
Conn:= false;
ifilebuf.Free;
Result := false;
exit;
end;
if Gauge<>nil then
Gauge.Progress:= Gauge.Progress+iret;
{ TODO : 发送剩余数据 }
icount:=icount+iret;
if icount<isumsend then
begin
for i:=0 to isumsend-icount-1 do
begin
isendbuf:=iitmpbuf[icount+i];
end;
ilen:=isumsend-icount;
end
else
begin
break;
end;
end;
end;
until isumsend-8 <= 0;
if ifilebuf<>nil then
begin
ifilebuf.Free;
ifilebuf:= nil;
end;


接收方:
procedure TTHSocketWork.Execute;
var
dwIndex: DWORD;
dwBytesTransferred,i: DWORD;
Sock_Error: DWORD;
buffer: array [0..DATA_BUFSIZE+2] of char;
TempBuffer: array [0..DATA_BUFSIZE] of char;
reveint: integer;
begin
inherited;
if idposition <> -1 then
begin
try
while not terminated do
begin
CoInitialize(nil);
dwBytesTransferred:= 0;
dwIndex:= WSAWaitForMultipleEvents(USEDataPool.GetItems[idposition].dwEventTotal
,@(USEDataPool.GetItems[idposition].EventArray) ,false ,WSA_INFINITE,false);
dwIndex:= dwIndex-WSA_WAIT_EVENT_0;
WSAResetEvent(USEDataPool.GetItems[idposition].EventArray[dwIndex]);
WSAGetOverlappedResult(USEDataPool.GetItems[idposition].SockSign, @USEDataPool.GetItems[idposition].AcceptOverlapped,
@dwBytesTransferred, false,USEDataPool.GetItems[idposition].Flags);
if dwBytesTransferred = 0 then
begin
WSACloseEvent(USEDataPool.GetItems[idposition].EventArray[dwIndex]);
HCCloseSocket(USEDataPool.PutItems(idposition).SockSign);
USEDataPool.PutItems(idposition).dwEventTotal:= USEDataPool.PutItems(idposition).dwEventTotal-1;
Suspend;
Continue;
end;
USEDataPool.GetItems[idposition].Flags:= 0;
ZeroMemory(@USEDataPool.PutItems(idposition).AcceptOverlapped, sizeof(TOverlapped));
USEDataPool.PutItems(idposition).AcceptOverlapped.hEvent:=
USEDataPool.GetItems[idposition].EventArray[dwIndex];
if dwBytesTransferred<>0 then
begin
reveint:= USEDataPool.GetItems[idposition].dwRecvBytes;
ZeroMemory(@TempBuffer, DATA_BUFSIZE);
fullchar(TempBuffer, USEDataPool.PutItems(idposition).DataBuf.buf);
reveint:= length(USEDataPool.PutItems(idposition).DataBuf.buf);
USEDataPool.PutItems(idposition).dealdata.position := USEDataPool.PutItems(idposition).dealdata.Size;
USEDataPool.PutItems(idposition).dealdata.WriteBuffer(TempBuffer,reveint);
DataAnalyse(USEDataPool.GetItems[idposition].dealdata,USEDataPool.GetItems[idposition].name);
if USEDataPool.PutItems(idposition).name<>'' then
begin
SetPackSize(USEDataPool.GetItems[idposition].name,USEDataPool.PutItems(idposition).DataBuf.len);
end;
end;
Application.ProcessMessages;
ZeroMemory(@buffer, DATA_BUFSIZE);
USEDataPool.PutItems(idposition).DataBuf.len:= DATA_BUFSIZE;
USEDataPool.PutItems(idposition).DataBuf.buf:= buffer;
Sock_Error:= WSARecv(USEDataPool.PutItems(idposition).SockSign ,
@USEDataPool.GetItems[idposition].DataBuf,1,
USEDataPool.GetItems[idposition].dwRecvBytes,
USEDataPool.GetItems[idposition].Flags,
@USEDataPool.GetItems[idposition].AcceptOverlapped, nil);
if SOCKET_ERROR=Sock_Error then
begin
if(WSAGetLastError()<>WSA_IO_PENDING) then
begin
WSACloseEvent(USEDataPool.GetItems[idposition].EventArray[dwIndex]);
HCCloseSocket(USEDataPool.PutItems(idposition).SockSign);
end;
end;
CoUninitialize;
end;
finally
HCCloseSocket(isocket);
end;
end
else
begin
HCCloseSocket(isocket);
end;
end;
 
顶,怎么了,没有见过次问题吗?
 
水平不够,俺只会看20行内的代码。。。代码太多,变量太多,俺就头晕
 
求大家了帮帮忙吧
 
.......代码太长了 看的头晕
没用过TTHSocketWork
一般我都把字符放到stream里 然后发送stream的数据流
 
那位高人能,解答我在加700分
 
那位高人能,解答我在加700分
 
那位高人能,解答我在加700分
 
if dwBytesTransferred<>0 then
begin
// 1:
reveint:= USEDataPool.GetItems[idposition].dwRecvBytes;
ZeroMemory(@TempBuffer, DATA_BUFSIZE);
// 2:
fullchar(TempBuffer, USEDataPool.PutItems(idposition).DataBuf.buf);
// 3:
reveint:= length(USEDataPool.PutItems(idposition).DataBuf.buf);

注解1错了吧,GetOverlappedResult得到完成的字节数: BytesOfTransferred,你干嘛还用
reveint:= USEDataPool.GetItems[idposition].dwRecvBytes;
注解2的代码是什么?
注解3跟注解1的代码重复。且Length(const S: string),传入PChar后,会转换string,而PPChar->string,会截掉#0后面的部分

BTW:你的代码真难看,BS一下。
 
多人接受答案了。
 
后退
顶部