我在winsock里的recv接收数据始终不正确,小菜想了好久了,还是想不到办法 ( 积分: 20 )

  • 主题发起人 主题发起人 pniker
  • 开始时间 开始时间
P

pniker

Unregistered / Unconfirmed
GUEST, unregistred user!
我想用winsock写一个客户/服务的模式程序,服务端监听端口后用telnet能正确的显示数据在cmd下,可是用我写的客户端却总是返回-1的结果到我的edit控件中,想了好久不知道问题出哪了,小菜我刚进富翁不久,分不多,但是恳请大家不佞赐教。

我的客户端代码:
const
s_port=803;
var
ws:WSADATA;
sock_addr:sockaddr_in;
sockfd,size1:integer;
v:byte;
begin
WSASTARTUP(MAKEWORD(2,2),ws);
sockfd:=socket(AF_INET,SOCK_STREAM,0);

sock_addr.sin_family:=AF_INET;
sock_addr.sin_port:=htons(s_port);
sock_addr.sin_addr.S_addr:=inet_addr('127.0.0.1');

Connect(sockfd,sock_addr,sizeof(sock_addr));
size1:=recv(sockfd,v,sizeof(v),0);
edit1.Text:=inttostr(size1);
Closesocket(sockfd);
end;

服务端代码:
const
s_port=830;
BackLog=10;
var
ws:wsadata;
sock_addr:sockaddr_in;
sockfd,newfd,size1:integer;
size2:char;
begin
WSASTARTUP(Makeword(2,2),ws);
sockfd:=socket(AF_INET,SOCK_STREAM,0);

sock_addr.sin_family:=AF_INET;
sock_addr.sin_port:=htons(s_port);
sock_addr.sin_addr.S_addr:=INADDR_ANY;

bind(Sockfd,sock_addr,sizeof(sock_addr));
listen(Sockfd,BackLog);
size1:=sizeof(sock_addr);
Newfd:=Accept(Sockfd,@sock_addr,@size1);
size2:='w';
Send(newfd,size2,sizeof(size2),0);
closesocket(sockfd);
closesocket(newfd);
end;
 
我想用winsock写一个客户/服务的模式程序,服务端监听端口后用telnet能正确的显示数据在cmd下,可是用我写的客户端却总是返回-1的结果到我的edit控件中,想了好久不知道问题出哪了,小菜我刚进富翁不久,分不多,但是恳请大家不佞赐教。

我的客户端代码:
const
s_port=803;
var
ws:WSADATA;
sock_addr:sockaddr_in;
sockfd,size1:integer;
v:byte;
begin
WSASTARTUP(MAKEWORD(2,2),ws);
sockfd:=socket(AF_INET,SOCK_STREAM,0);

sock_addr.sin_family:=AF_INET;
sock_addr.sin_port:=htons(s_port);
sock_addr.sin_addr.S_addr:=inet_addr('127.0.0.1');

Connect(sockfd,sock_addr,sizeof(sock_addr));
size1:=recv(sockfd,v,sizeof(v),0);
edit1.Text:=inttostr(size1);
Closesocket(sockfd);
end;

服务端代码:
const
s_port=830;
BackLog=10;
var
ws:wsadata;
sock_addr:sockaddr_in;
sockfd,newfd,size1:integer;
size2:char;
begin
WSASTARTUP(Makeword(2,2),ws);
sockfd:=socket(AF_INET,SOCK_STREAM,0);

sock_addr.sin_family:=AF_INET;
sock_addr.sin_port:=htons(s_port);
sock_addr.sin_addr.S_addr:=INADDR_ANY;

bind(Sockfd,sock_addr,sizeof(sock_addr));
listen(Sockfd,BackLog);
size1:=sizeof(sock_addr);
Newfd:=Accept(Sockfd,@sock_addr,@size1);
size2:='w';
Send(newfd,size2,sizeof(size2),0);
closesocket(sockfd);
closesocket(newfd);
end;
 
GetLastError()一下。
 
不行呢:(
 
Connect()
返回成功没有?
 
你的程序检错性太弱了,都不检查函数调用是否成功。。。
你看看服务端监听的是830端口,客户端连的是803端口,-.-b
另,如要自己绑定端口的话,尽量不要用4000一下的端口(尤其1024之前的系统保留端口不要用)
 
to:islet8
大大教训的是,不过因为这个是练习写的,所以没加容错语句处理.
不知道有没有相关的例程可以参考.
端口错误这里我改过来了,错误是没有了,不过收到的一个整型数^_^!我一直郁闷的地方就是Server端的recv是integer的,要转成String的显示在edit控件里,可是我不知道怎么弄这里好了。请大家赐教。
 
这就是另外一个你程序的问题了,刚才没说,就是你客户端接收的是后调用recv()用于保存接收数据的是一个byte类型的变量-.-b
所以变成你所说的整型了。。
注意看看recv()的msdn文档,
int recv (
SOCKET s,
char FAR* buf, // 看这里,是字符串类型(c/c++里面的,其实是个字符串首地址,类似delphi下的PChar类型)
int len,
int flags
);
所以,你应该知道怎么解决了吧:)
 
接收可以了,不过是乱码
 
问题还是没解决,我把数据类型修改了,可是收到的是乱码
Server端的:
const
s_port=10000;
BackLog=10;
var
ws:wsadata;
sock_addr:sockaddr_in;
sockfd,newfd,size1:integer;
size2:Pchar;
begin
WSASTARTUP(Makeword(2,2),ws);
sockfd:=socket(AF_INET,SOCK_STREAM,0);

sock_addr.sin_family:=AF_INET;
sock_addr.sin_port:=htons(s_port);
sock_addr.sin_addr.S_addr:=INADDR_ANY;

bind(Sockfd,sock_addr,sizeof(sock_addr));
listen(Sockfd,BackLog);
size1:=sizeof(sock_addr);
Newfd:=Accept(Sockfd,@sock_addr,@size1);
size2:='www830';
Send(newfd,size2,sizeof(size2),0);
closesocket(sockfd);
closesocket(newfd);
end;

Client端:
const
s_port=10000;
var
ws:WSADATA;
sock_addr:sockaddr_in;
sockfd:integer;
buf:Pchar;
begin
WSASTARTUP(MAKEWORD(2,2),ws);
sockfd:=socket(AF_INET,SOCK_STREAM,0);

sock_addr.sin_family:=AF_INET;
sock_addr.sin_port:=htons(s_port);
sock_addr.sin_addr.S_addr:=INADDR_ANY;

Connect(sockfd,sock_addr,sizeof(sock_addr));

recv(sockfd,buf,sizeof(buf),0);
Edit1.Text:=buf;

Closesocket(sockfd);
end;
 
PChar其实是一个C的字符串指针(类似char *)类型,所以你客户端程序里要给它分配一块实际内存空间
通常的做法是定义一个固定大小(较大)的接受缓冲区,然后把首地址传给recv()函数
private
FRecvBuf: array[1..8192] of Char;
...
recv(FSocket, @FRecvBuf, SizeOf(FRecvBuf), 0);
 
谢谢大大islet8指点,问题解决了,分不多,不过是小菜的心意。[:D]
 
接受答案了.
 
后退
顶部