zw84611,哥们,帮着看看了,昨天的继续问题。关于UDP发送接受的问题。(0分)

C

cjsam

Unregistered / Unconfirmed
GUEST, unregistred user!
麻烦看看了:

触发了收到数据的那个消息里面定义流你能看看有什么问题吗?我收到的全是空的。
procedure TLogin_frm.ReadData(var Message: TMessage);
var
len: integer;
flen: integer;
Event: word;
MyStream: TMemoryStream;
TmpStr:TCommDataFormat;
ordercode:integer;
begin
flen:=sizeof(FSockAddrIn);
FSockAddrIn.SIn_Port := htons(UDPPORT);
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
MyStream := TMemoryStream.Create;
Mystream.Position:=0;
recvfrom(sock,Mystream.memory^,sizeof(Mystream),0,FSockAddrIn,flen);
end;
MyStream.Read(TmpStr,Mystream.Size);
ordercode:=TmpStr.Head;//显示定义的结构的头的内容。
end;
里面 TmpStr这个变量里面是空的,什么都收不到。
 
在recvfrom之前加上
MyStream.SetSize(sizeof(TmpStr))
试一下。
 
to :zw84611,
又得麻烦你了,我发现了一个问题,不得其解。程序的其他主体做完了,就这还是有问题。
客户发送端的函数中
procedure SendData(content: TMemoryStream);
var
len:integer;
begin
FSockAddrIn.SIn_Addr.S_addr := inet_addr(PChar(Hostname));
FSockAddrIn.SIn_Port := htons(strtoint(port));
[red]len := sendto(sock, content.Memory^, sizeof(content), 0, FSockAddrIn, sizeof(FSockAddrIn));[/red]
if (WSAGetLastError() <> WSAEWOULDBLOCK) and (WSAGetLastError() <> 0) then
begin
MessageBox(handle,'SOCKET错误,代码:','提示',mb_ok);
WriteLog(now,'SOCKET错误,代码:'+inttostr(WSAGetLastError()));
exit;
end;
if len = SOCKET_ERROR then
begin
MessageBox(handle,'数据发送失败!','提示',mb_ok);
WriteLog(now,'数据发送失败!');
exit;
end;
if len<>sizeof(content) then
begin
MessageBox(handle,'数据发送不完整!','提示',mb_ok);
end;
end;
红色那一行
len := sendto(sock, content.Memory^, sizeof(content), 0, FSockAddrIn, sizeof(FSockAddrIn));
这样写发送这个流,服务端收到的数据能显示这个包的IP/PORT,没问题。但是包的长度不管]
数据是什么,都是4个长度,也就是sizeof(TMemoryStream)永远都是4个字节,不太清楚这是
什么原因,这个函数SIZEOF(S)好象返回是S的使用的字节长度,是不是只是返回TMemoryStream
占有的定义空间站用的地址量,不知道到地是什么原因。
[red]当这样写流的尺寸的时候,
len := sendto(sock, content.Memory^, content.size, 0, FSockAddrIn, sizeof(FSockAddrIn));
服务端收到的包的数据正确,但是就是没有PORT/IP,这就和采用控件直接做结果一样。请问
这是什么原因。我实在想不明白了。
[/red]
哎!麻烦你了,以前从来没做过通讯程序,只是做一些和数据库相关的东西。所以现在碰到的问题
就多,请多包涵,因为知道你是这里的牛人了。



 
对与一个TMemoryStream他的sizeof(TMemoryStream),是不是只对一个指针的尺寸所以
返回的都是4个字节长度呀。如果用TMemoryStream.size的话返回的是这个的总长度,那摸
为什么发出去的包里没有IP/PORT呢?
 
>>对与一个TMemoryStream他的sizeof(TMemoryStream),是不是只对一个指针的尺寸所以
>>返回的都是4个字节长度呀
应该是,我试了一下SizeOf(TForm)也是4。

>>TMemoryStream.size的话返回的是这个的总长度
我以前没用过TMemoryStream,MyStream.Size也总是4吗?
 
>>当这样写流的尺寸的时候,
>>len := sendto(sock, content.Memory^, content.size, 0, FSockAddrIn, sizeof(FSockAddrIn));
>>服务端收到的包的数据正确,但是就是没有PORT/IP,这就和采用控件直接做结果一样。请问
>>这是什么原因。我实在想不明白了。

抱歉,我刚刚没看到这一段。是很奇怪,前几天看到过有一个和这类似的问题,我找找。
 
MyStream.Size这个不是的,这是具体的长度
但是
len := sendto(sock, content.Memory^, content.size, 0, FSockAddrIn, sizeof(FSockAddrIn));
他发出去后收到的包用
recvfrom收到的,里面显示不出来IP/PORT号的。
 
前几天看到过有一个和这类似的帖子,没有解决,一时找不到了。我不知道是为什么,不知是否
和Stream有关。其实你可以直接发送二进制数据的,不一定要用流。

var buffer: ^byte;

GetMem(buffer, content.size);
CopyMemory(buffer, content.Memory, content.size);
sendto(sock, buffer, content.size, 0, FSockAddrIn, sizeof(FSockAddrIn));
FreeMemory(buffer);
接收时也可以不用流,试一下吧。

另外我这里HTML标记似乎不起作用。
 
如果我这样写的话,
var buffer: ^byte;
GetMem(buffer, content.size);
CopyMemory(buffer, content.Memory, content.size);
sendto(sock, buffer, content.size, 0, FSockAddrIn, sizeof(FSockAddrIn));
FreeMemory(buffer);
服务端(VC写的)收到我的包里没有IP/PORT,但是好象数据是对的,但是我改成:
sendto(sock, buffer, sizeof(content), 0, FSockAddrIn, sizeof(FSockAddrIn));
或者:
sendto(sock, buffer, sizeof(buffer), 0, FSockAddrIn, sizeof(FSockAddrIn));
服务端(VC写的)收到我的包的IP/PORT对了,但是数据肯定错了,因为sizeof(buffer),
sizeof(content), 都是指针的长度呀,才4个字节,所以包的内容是错误。但是
IP/PORT对的。

 
那就不用象我那样改了。你的sizeof(content)有多大?
 
sizeof(content)=4
content.size是正确的,是512
但是到底是什么原因呢?发不出去呢?
 
哈哈,原来上次的那个问题也是你提的。

不是发不出去,而是用recvfrom得不到IP和port。你让他用CSocket.GetPeerName()得到IP和Port试试。
 
另外
Type
TDataFormat=record
Head:Byte;
SerNumber:Byte;
StreamLen:array[0..1] of byte;
stream:array [0..512] of char;
end;

array [0..512] of char的大小是513,array [0..511] of char的大小才是512

 
to zw84611:
对呀上次的问题也是我的,但是我当时说了的呀,用recvfrom只有在长度很短的情况下可以
收到IP/PORT的,长度长了就收不到了。那又是为什么呢。
我当时贴的帖子上,是这样写的:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1446279

//array [0..512] of char的大小是513,array [0..511] of char的大小才是512
这个是的,我程序里是511,我考到这来的时候可能改了的。

 
对方用CSocket.GetPeerName()是否可以得到IP和Port?
另外你是只发送了其中的stream还是把整个结构都发出去了?
 
to zw84611:
CSocket.GetPeerName()不是真对有连接的吗?如果用在UDP里我得不到对方的SOCKET,好象得不
到IP/PORT,不知道是不是。我试了下得不到呀
 
我发送的是正个结构。因为这个整个结构是一个协议的组成,首到包的要安这个还原出来
 
ok,GetPeerName是我搞错了。
我真是没办法了,不知道问题出在你这里还是在那个VC程序上。
试试发送(content.size-1)或更小一些的数据看看还是不是这样。
 
to zw84611:
呵呵,不好意思,我也是没办法,我也急的不的了。

len := sendto(sock, content.Memory^, [red]10[/red], 0, FSockAddrIn, sizeof(FSockAddrIn));

这是个极限长度,红色的,10个,11个的时候就收不到了。
 
faint, 还会有这种事,能不能把VC的相关代码帖出来。
 
顶部