程序采用udp socket进行通信,用winsock api函数实现,C/S结构。C给S发来数据包,如何实现在S端从这个包中取C端的IP和主机名?getpeername()好像只支持面向连接的socket.
如上述实现不了,我准备这样做:先在C端直接得到C的IP和主机名,然后再直接发给S,S收到这个包再取出,不知这样行不?有更直接的方法吗?
先谢了!!!
如上述实现不了,我准备这样做:先在C端直接得到C的IP和主机名,然后再直接发给S,S收到这个包再取出,不知这样行不?有更直接的方法吗?
先谢了!!!
char FAR* buf,
int len,
int flags,
struct sockaddr FAR* from,
int FAR* fromlen
);其中from这个sockaddr包含了发送段工作站的地址
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,WinSock, Sockets;type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TThreadRead=class(TThread)
private
FK :TSocket;
fbuf : array[0..255] of char;
add : TSockAddrIn;
procedure GetInfo; public
constructor Create(sock : TSocket);
procedure Execute;override;
end;var
Form1: TForm1;
SSock : TSocket;
WSAData : TWSAData;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
ErrorCode : integer;
SockAdd_In : TSockAddrIn;
begin
//创建一个“服务器”段,其实就是用来接受数据的
SSock := socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if SSock = SOCKET_ERROR then
begin
showmessage(Format('%s;ErrorCode:%d',['½¨Á¢Ì×½Ó×Öʧ°Ü',WSAGetLastError]) );
Exit;
end; SockAdd_In.sin_family := PF_INET;
SockAdd_In.sin_port := htons(5150);
SockAdd_In.sin_addr.S_addr := htonl(INADDR_ANY);
//绑定
ErrorCode := bind(SSock,SockAdd_In,sizeof(SockAdd_In));
if ErrorCode = SOCKET_ERROR then
begin
showmessage(Format('%s;ErrorCode:%d',['°ó¶¨Ì×½Ó×Öʧ°Ü',WSAGetLastError]) );
Exit;
end;
//建立一个读线程用来读取数据
TThreadRead.Create(SSock); // FAcceptSockThread := TAcceptSockThread.Create(FSock);
end;{ TThreadRead }constructor TThreadRead.Create(sock: TSocket);
begin
FK := sock;
inherited Create(false);
end;procedure TThreadRead.Execute;
var
tm : integer;
begin
while not terminated do
begin
tm := sizeof(add);
if recvfrom(FK,fbuf,256,0,add,tm) > 0 then
begin
Synchronize(GetInfo);
Sleep(0);
end; end;
end;procedure TThreadRead.GetInfo;
var
s : string;
begin
s := fbuf;
s := s+#13 + inet_ntoa(add.sin_addr);
Form1.Memo1.Lines.Add(s);
end;procedure StartUp;
var
ErrorCode : integer;
begin
ErrorCode := WSAStartup($0101, WSAData);
if ErrorCode <> 0 then
begin
ShowMessage('¼ÓÔØʧ°Ü');
exit;
end;
end;
//发送端
procedure TForm1.Button2Click(Sender: TObject);
var
ErrorCode : integer;
buf : array[0..255] of Char;
SockAddTo : TSockAddrIn;
SkC : TSocket;
begin skc := socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if skc = SOCKET_ERROR then
begin
showmessage('加载失败);
Exit;
end; SockAddTo.sin_family := PF_INET;
SockAddTo.sin_port := htons(5150);
SockAddTo.sin_addr.S_addr := inet_addr('192.168.1.3'); buf :='wudi_1982';
sendto(SkC,buf,256*sizeof(char),0,SockAddTo,sizeof(SockAddTo)); closesocket(skc);end;initialization
StartUp;
finalization
WSACleanup;end.
这种方法可以得到发送方的IP,但是发送方的主机名还是通过数据包主动发给接收方的:
buf :='wudi_1982';
sendto(SkC,buf,256*sizeof(char),0,SockAddTo,sizeof(SockAddTo));
还有其他的方法吗?能直接得到发送方的主机名的?