初次使用完成端口,有很多不懂的地方,请大侠们指导指导。以前一直用delphi自带的控件ServerSocket,此控件提供了一个OnAccept事件,可以在这个事件里,来得到连接的客户端信息,比如客户端地址、端口号,和所谓的注册包(连接建立是发送过来的字符串)信息,通过这些信息来判断客户端的合法性,以决定是允许此连接还是拒绝此连接。现在开始用完成端口写,高了半天也不知道从那里来得到这些信息,有人说用getpeername可以得到客户端的ip和端口号信息,用tcp/ip的外带数据可以实现注册包的方式,但是具体不知道如何操作,希望在连接和完成端口建立关联之前实现此认证操作。请了解的提供帮忙,不胜感激
while True do
begin
Acceptsc :=WSAAccept(Listensc, Nil, Nil, Nil, 0);
if Acceptsc =SOCKET_ERROR then
begin
closesocket(Listensc);
Exit;
end;
//感觉应该在这个地方加入对Acceptsc 的验证
end;
while True do
begin
Acceptsc :=WSAAccept(Listensc, Nil, Nil, Nil, 0);
if Acceptsc =SOCKET_ERROR then
begin
closesocket(Listensc);
Exit;
end;
//感觉应该在这个地方加入对Acceptsc 的验证
end;
getpeername(FSocket, SockAddrIn, Size)
inet_ntoa(SockAddrIn.sin_addr) 连接socket的ip地址
ntohs(SockAddrIn.sin_port) 连接socket的端口
2、用acceptex接受
GetAcceptExSockAddrs分析缓冲区
GetAcceptExSockAddrs(@AOperation.FBuffer.AcceptExBuffer[0],0,
SizeOf(TSockAddr) + 16, SizeOf(TSockAddr) + 16,tLocalAddr,iLocalAddrLen,
tRemoteAddr,iRemoteAddrLen );可得地址和端口
getpeername(FSocket, SockAddrIn, Size)
inet_ntoa(SockAddrIn.sin_addr) 连接socket的ip地址
ntohs(SockAddrIn.sin_port) 连接socket的端口
2、用acceptex接受
GetAcceptExSockAddrs分析缓冲区
GetAcceptExSockAddrs(@AOperation.FBuffer.AcceptExBuffer[0],0,
SizeOf(TSockAddr) + 16, SizeOf(TSockAddr) + 16,tLocalAddr,iLocalAddrLen,
tRemoteAddr,iRemoteAddrLen );可得地址和端口
getpeername(FSocket, SockAddrIn, Size)
inet_ntoa(SockAddrIn.sin_addr) 连接socket的ip地址
ntohs(SockAddrIn.sin_port) 连接socket的端口
2、用acceptex接受
GetAcceptExSockAddrs分析缓冲区
GetAcceptExSockAddrs(@AOperation.FBuffer.AcceptExBuffer[0],0,
SizeOf(TSockAddr) + 16, SizeOf(TSockAddr) + 16,tLocalAddr,iLocalAddrLen,
tRemoteAddr,iRemoteAddrLen );可得地址和端口
下面一步,怎们能得到注册包的信息呢。
keeley20 说的方法不是不可行,但是这样处理的话,就要在每次通讯受到包的时候都去判断一次,很频繁的通讯开销太大,另外,我要通过注册信息判断出是哪个连接上来的,好对应词连接做一些初始化工作。想再建立连接的时候判断完毕,以后就是可信任的连接了,就不在做判断了,所以最好还是在跟完成端口绑定之前做比较好
begin
closesocket(Listensc);
Result :=6;
Continue;
end;
//***********************获取客户端IP地址和端口号 **************
FillChar(ClientIPAddress, Length(ClientIPAddress), #0);
StrMove(ClientIPAddress, inet_ntoa(sti.sin_addr), Length(ClientIPAddress));
ClientPort :=ntohs(sti.sin_port);
//***********************获取注册字符串*************
FillChar(RegisterStr, Length(RegisterStr), #0);
if Recv(Acceptsc, RegisterStr, Length(RegisterStr), MSG_OOB) <>0 then
begin;
end;
这样代码倒是可以接受注册包了,(把注册包当成客户端发送的一条数据来接受),接收后再处理完成端口的初始化工作,但是对于不发送注册包的设备,就一直停止在recv事件了
NS: Integer;
Addr: SOCKADDR_IN;
AddrLen: Integer; Host: Longword;
Port: Word;
while True do
begin
AddressLen := SizeOf(Address);
NS := WSAAccept(TcpServer.Socket, @Addr, @AddrLen, nil, 0);
if NS = INVALID_SOCKET then
begin
Break;
end;
Host := htonl(Address.sin_addr.S_addr);
Port := Address.sin_port;
end;