急,winsock api问题

diablobaal 2010-03-23 03:54:47
小弟对winsock api不熟,现要通讯一个电表,用vb已实现,代码详见http://topic.csdn.net/u/20100118/10/46b7f270-9077-458c-812b-82ee1260a343.html
在网上查了一段代码,将vb代码改为如下的delphi代码——
function GetDatax(IP:String;startaddress:integer;datacount:integer): TResultArray;
var
Errorcode,AddSize:Integer;
ret:Integer;
WSAData : TWSAData;//一个数据结构,包含winsock的所有属性
Skc : TSocket;//套接字
SockAdd_Inc,Add : TSockAddrIn;//套接字的数据结构,包含套接字的所有属性
order:array[0..11] of char;//命令数组
FSocket : TSocket;
FBuf : TResultArray;
i:Integer;
tempx:Integer;
begin
//*********************加载WinSock动态链接库
Errorcode:=WSAStartup($0101,WSAData);//加载winsock库
if Errorcode<>0 then//WSAStartup方法,必须通过了才能使用winsock api
begin
ShowMessage('加载WinSock动态链接库失败');
result:=fbuf;
exit;
end;
//*********************在客户端创建一个套接字
skc := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if skc = SOCKET_ERROR then
begin
showmessage('创建套接字失败');
result:=fbuf;
Exit;
end;
SockAdd_Inc.sin_family := AF_INET;
SockAdd_Inc.sin_port := htons(502);
SockAdd_Inc.sin_addr.S_addr := inet_addr(pchar(IP));
//*********************连接服务器
tempx:=connect(skc,SockAdd_Inc,sizeof(SockAdd_Inc));
//*********************发送数据
order[0] := chr(0); //交换识别号高字节,通常为0
order[1] := chr(0); //交换识别号低字节,通常为0
order[2] := chr(0); //协议识别号高字节,为0
order[3] := chr(0); //协议识别号低字节,为0
order[4] := chr(0); //以下字节长度高字节
order[5] := chr(6); //以下字节长度低字节
order[6] := chr(1); //单元识别号,确省为255,即地址
order[7] := chr(3); //功能代码
order[8] := chr(startaddress div 256); //读数据的起始地址高字节
order[9] := chr(startaddress Mod 256); //读数据的起始地址低字节
order[10] := chr((datacount * 2) div 256); //显示的参数长度高字节
order[11] := chr((datacount * 2) Mod 256); //显示的参数长度低字节
send(SkC,order,12,0);
//*********************接收数据
AddSize := sizeof(Add);
FSocket:=accept(skc,@Add,@AddSize);
ret := recv(FSocket,fbuf,256,0);
if ret<=0 then
begin
ShowMessage('接收数据失败');
shutdown(skc,SD_SEND);
closesocket(skc);
result:=fbuf;
exit;
end;
//*********************断开连接
shutdown(skc,SD_SEND);
closesocket(skc);
result:=fbuf;
end;

但没有收到任何数据,单步调试发现tempx:=connect(skc,SockAdd_Inc,sizeof(SockAdd_Inc));
tempx=0,不知代码错在哪,请高手指教
...全文
114 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
sanguomi 2010-03-24
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 diablobaal 的回复:]
解决了,
将AddSize := sizeof(Add);
FSocket:=accept(skc,@Add,@AddSize);
ret := recv(FSocket,fbuf,256,0);
改为ret := recv(skc,fbuf,256,0);一句就行了
我是读电表,所以是客户端程序,不需要BIND 和LISTEN的
[/Quote]

上边我就说了,你的客户端多了个ACCEPT
diablobaal 2010-03-24
  • 打赏
  • 举报
回复
我是下了“深入Delphi6网络编程”这本书仔细研究后解决的,所以推荐一下此书
diablobaal 2010-03-24
  • 打赏
  • 举报
回复
解决了,
将AddSize := sizeof(Add);
FSocket:=accept(skc,@Add,@AddSize);
ret := recv(FSocket,fbuf,256,0);
改为ret := recv(skc,fbuf,256,0);一句就行了
我是读电表,所以是客户端程序,不需要BIND 和LISTEN的
sanguomi 2010-03-24
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 mdejtod 的回复:]
TCP是不需要BIND 和LISTEN的
长见识了,但是怎么我把服务器端的端口绑定和监听去掉后,客户端连接不上呢?
[/Quote]
从楼主的代码来看,应该TCPClient, TCP是不需要BIND 和LISTEN的,
你看不出是TCP那里少打了个TCPCLIENT,你自己要怎么理解我也没办法
SQLDebug_Fan 2010-03-24
  • 打赏
  • 举报
回复
解决问题就好了,网络编程要多实践。
mdejtod 2010-03-23
  • 打赏
  • 举报
回复
TCP是不需要BIND 和LISTEN的
长见识了,但是怎么我把服务器端的端口绑定和监听去掉后,客户端连接不上呢?
sanguomi 2010-03-23
  • 打赏
  • 举报
回复
从楼主的代码来看,应该TCPClient, TCP是不需要BIND 和LISTEN的,但是那个ACCEPT却是多余的
connect(skc,SockAdd_Inc,sizeof(SockAdd_Inc));
这句报错的话,你应该去检查的服务端,比如端口是不是一样的,
另外加个
try
connect(skc,SockAdd_Inc,sizeof(SockAdd_Inc));
finally
ShowMessage(SysErrorMessage(WSAGetLastError));
end;
SQLDebug_Fan 2010-03-23
  • 打赏
  • 举报
回复
把MSDN的帮助给你
int connect(
__in SOCKET s,
__in const struct sockaddr* name,
__in int namelen
);
Parameters
s
Descriptor identifying an unconnected socket.

name
Name of the socket in the sockaddr structure to which the connection should be established.

namelen
Length of name, in bytes.
例子

#include <stdio.h>
#include "winsock2.h"

void main() {
//----------------------
// Initialize Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR)
printf("Error at WSAStartup()\n");

//----------------------
// Create a SOCKET for connecting to server
SOCKET ConnectSocket;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return;
}

//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
clientService.sin_port = htons( 27015 );

//----------------------
// Connect to server.
if ( connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) {
printf( "Failed to connect.\n" );
WSACleanup();
return;
}

printf("Connected to server.\n");
WSACleanup();
return;
}
mdejtod 2010-03-23
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 kfcoffe 的回复:]
tempx:=connect(skc,SockAdd_Inc,sizeof(TSockAddrIn));//这里错了,应该是这个结构的大小,而不是你申明的变量大小。
[/Quote]
一样的,
你的服务器端SOCK是怎么创建的,代码呢?
给你一段服务器端的代码例子

FSock := socket(PF_INET,SOCK_STREAM , IPPROTO_TCP);
if FSock = SOCKET_ERROR then
begin
showmessage(Format('%s;ErrorCode:%d',['套接字创建失败',WSAGetLastError]) );
Exit;
end;
//根据一个TCheckBox控件的选择情况来决定使用锁定模式还是非锁定模式
if chkLock.Checked then
tm := 1 //非锁定模式
else tm := 0; //锁定模式
ioctlsocket(FSock,FIONBIO,tm);
SockAdd_In.sin_family := PF_INET;
SockAdd_In.sin_port := htons(5151);
SockAdd_In.sin_addr.S_addr := INADDR_ANY;
ErrorCode := bind(FSock,SockAdd_In,sizeof(SockAdd_In));
if ErrorCode = SOCKET_ERROR then
begin
showmessage(Format('%s;ErrorCode:%d',['绑定失败:',WSAGetLastError]) );
Exit;
end;
//置为监听模式 backlog参数指定了正在等待连接的最大队列长度
listen(FSock,5);
//调用WSAAsyncSelect或WSAEventSelect函数的时候,会将套接字自动设为非锁定模式
if SOCKET_ERROR=WSAAsyncSelect(FSock,Handle,WM_SERVERSOCK,FD_READ or FD_ACCEPT) then
ShowMessage('WM_SOCKET Error');
SQLDebug_Fan 2010-03-23
  • 打赏
  • 举报
回复
用GetLastError看一下是什么错误
dd_zhouqian 2010-03-23
  • 打赏
  • 举报
回复
server

bind
listen
kfcoffe 2010-03-23
  • 打赏
  • 举报
回复
tempx:=connect(skc,SockAdd_Inc,sizeof(TSockAddrIn));//这里错了,应该是这个结构的大小,而不是你申明的变量大小。
bdmh 2010-03-23
  • 打赏
  • 举报
回复
tempx := 0 说明连接成功,你的绑定和监听在哪里

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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