p1.*_*1.e 5 delphi winsock stream recv
我正在研究一个相当简单的客户端/服务器应用程序,并且在使用winsock API提供的recv从客户端接收TStringStream时遇到一些麻烦.
我不断收到此错误:'0x00000000访问冲突:读取地址0x00000000'.
客户端只将文本复制到TStringStream中,获取它的长度并将其发送到服务器.然后服务器接收Stream并输出它的文本.下面是一些抽象代码摘录.
{ the server's part }
inBuf := TStringStream.Create;
{ MAKE THIS SOCKET A PASSIVE ONE }
listen(serversock, LISTENQ);
{ ACCEPT CONNECTION ON serversock FROM cliaddr -> CONNECTED SOCKET = connfd }
connfd := accept(serversock, @cliaddr, @len);
recv(connfd, inLen, sizeof(inLen), 0);
//up to here everything is fine with the strem:
//Size = InLen, Position = 0, all bytes are '0'
rec := recv(connfd, inBuf, inLen, 0);
//rec = inLen, which is fine
//now this: inBuf: FMemory $1, FSize 9 (no matter how long the msg is)
// FPosition 7077987 and FBytes: many many random
DebugOutput(inBuf.DataString); //the error is thrown here
Run Code Online (Sandbox Code Playgroud)
其中connfd是连接套接字,servsock是监听套接字,inLen是包含inBuf长度的基数,inBuf是全局TStringStream.rec是一个基数,包含recv收到的字节数.
{ the client's send function }
function SSend(sock :TSocket; addr :sockaddr_in; msg :TStringStream) :Integer;
var
len: Cardinal;
begin
len := msg.Size;
send(sock, len, sizeof(len), 0);
msg.Seek(0,0);
send(sock, msg, sizeof(msg), 0);
Result := 0;
end;
Run Code Online (Sandbox Code Playgroud)
和客户对SSend的调用:
{ CREATE (OUTPUT)STREAM }
s := TStringStream.Create;
s.WriteString(_input.Text);
//_input is a TMemo with text, let's say, ´hello´
SSend(client, servaddr, s);
//client is a TSocket
Run Code Online (Sandbox Code Playgroud)
在此先感谢您的帮助!
p1.e
您将传入recv指向TStringStream对象本身的指针,而不是指向其数据缓冲区.这就是对象被破坏的原因.使用Memory财产:recv(connfd, inBuf.Memory^, inLen, 0).
发送也是如此:从流发送数据,而不是流对象(sizeof(msg)在SSend返回中只是指针的大小).
| 归档时间: |
|
| 查看次数: |
534 次 |
| 最近记录: |