C
cjsam
Unregistered / Unconfirmed
GUEST, unregistred user!
unit TsocketThread_p;
interface
uses
Classes,Sysutils,winsock,Messages,Dialogs;
const
WM_SOCK = WM_USER + 1;
type
TTSocketThread = class(TThread)
private
Fid:string;
FIp:string;
FPort:string;
sock: TSocket;
addr: TSockAddr;
FSockAddrIn : TSockAddrIn;
path:string;//记录该通讯日志的路径
protected
procedure Execute; override;
Procedure CreateSocket;
procedure ReadData(var Message: TMessage);message WM_SOCK;
procedure senddate;
public
Constructor create(Ip,port,id:string;
destructor Destroy; override;
end;
implementation
{ TTSocketThread }
{参数:
IP:远程机器IP
PORT:远程机器PORT
ID:一个线程建立通讯对应的ID。
}
constructor TTSocketThread.create(ip,port,id:string);
var
s:TDateTime;
begin
FIp:=ip;
FPort:=port;
Fid:=id;
CreateSocket;
inherited create(false);
end;
Procedure TTSocketThread.CreateSocket;
var
TempWSAData: TWSAData;
err:integer;
begin
path:='/'+Fid+'_comm.log';
addr.sin_family:=PF_INET;
addr.sin_port:=htons(strtoint(FPort));
addr.sin_addr.S_addr:=inet_addr(pchar(FIp));
err:=WSASTARTUP($101,TempWSAData);
IF err=0 THEN
BEGIN
WriteLog(now,'编号为:'+Fid+' 的SOCKET初始化成功',path);
sock:=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
IF SOCK=INVALID_SOCKET THEN
WriteLog(now,'编号为:'+Fid+' 的SOCKET初始化失败',path)
else
begin
WriteLog(now,'编号为:'+Fid+' 对应的线程SOCKET创建成功',path);
err:=CONNECT(sock,addr,sizeof(addr));
if err=socket_error then
begin
WriteLog(now,'编号为:'+Fid+' 的SOCKET连接通讯主机失败!',path);
err:=closesocket(sock);
if err=0 then
WriteLog(now,'编号为:'+Fid+' 的对应SOCKET释放成功!',path);
end
else
begin
WriteLog(now,'编号为:'+Fid+' 的对应SOCKET连接通讯主机成功!',path);
exit;
end;
end;
WSAcleanup;
end;
///********************************************
WSAAsyncSelect(sock, handle, WM_SOCK, FD_READ );
//将消息帮定,但是因为没有窗体,第二个参数到底怎样写呀。
//它的值取谁的 HANDLE
//*******************************************
end;
destructor TTSocketThread.Destroy;
begin
WriteLog(now,'ID:'+Ftelid+'通讯结束!',path);
inherited;
end;
procedure TTSocketThread.Execute;
var
len:integer;
begin
//FreeOnTerminate:=true;
senddate;
end;
procedure TTSocketThread.ReadData(var Message: TMessage);
var
flen: integer;
Event: word;
RecvBuff:array [0..1024] of char;
RecvS:string;
begin
flen:=sizeof(FSockAddrIn);
FSockAddrIn.SIn_Port := htons(strtoint(Fport));
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
recvfrom(sock,RecvBuff,sizeof(RecvBuff),0,FSockAddrIn,flen);
end;
end;
procedure TTSocketThread.senddate;
var
ret,len:integer;
s:string;
psendchar;
begin
s:='01,'+Fid+';';
len:=length(s);
psend:=stralloc(len);
Strpcopy(Psend,S);
ret:=send(sock,psend^,len,0);
WriteLog(now,s,path);
if ret=SOCKET_ERROR then
WriteLog(now,'发送 '+s+'失败',path);
end;
end.
请大家帮我看一下,我程序有什么问题?能够发送,服务端接受也正确。但是这个线程不能拦截服务端发送来的消息。收不到。
我想问下大家,创建SOCKET的时候,
addr.sin_family:=PF_INET;
addr.sin_port:=htons(strtoint(FPort));
addr.sin_addr.S_addr:=inet_addr(pchar(FIp));
err:=WSASTARTUP($101,TempWSAData);
这个里面对应的IP,PORT是远程服务端的IP,PORT吧?
那我线程中创建的SOCKET的自己 的IP,PORT是在那设置?我不太清楚API创建SOCKET的关系。谢谢。
interface
uses
Classes,Sysutils,winsock,Messages,Dialogs;
const
WM_SOCK = WM_USER + 1;
type
TTSocketThread = class(TThread)
private
Fid:string;
FIp:string;
FPort:string;
sock: TSocket;
addr: TSockAddr;
FSockAddrIn : TSockAddrIn;
path:string;//记录该通讯日志的路径
protected
procedure Execute; override;
Procedure CreateSocket;
procedure ReadData(var Message: TMessage);message WM_SOCK;
procedure senddate;
public
Constructor create(Ip,port,id:string;
destructor Destroy; override;
end;
implementation
{ TTSocketThread }
{参数:
IP:远程机器IP
PORT:远程机器PORT
ID:一个线程建立通讯对应的ID。
}
constructor TTSocketThread.create(ip,port,id:string);
var
s:TDateTime;
begin
FIp:=ip;
FPort:=port;
Fid:=id;
CreateSocket;
inherited create(false);
end;
Procedure TTSocketThread.CreateSocket;
var
TempWSAData: TWSAData;
err:integer;
begin
path:='/'+Fid+'_comm.log';
addr.sin_family:=PF_INET;
addr.sin_port:=htons(strtoint(FPort));
addr.sin_addr.S_addr:=inet_addr(pchar(FIp));
err:=WSASTARTUP($101,TempWSAData);
IF err=0 THEN
BEGIN
WriteLog(now,'编号为:'+Fid+' 的SOCKET初始化成功',path);
sock:=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
IF SOCK=INVALID_SOCKET THEN
WriteLog(now,'编号为:'+Fid+' 的SOCKET初始化失败',path)
else
begin
WriteLog(now,'编号为:'+Fid+' 对应的线程SOCKET创建成功',path);
err:=CONNECT(sock,addr,sizeof(addr));
if err=socket_error then
begin
WriteLog(now,'编号为:'+Fid+' 的SOCKET连接通讯主机失败!',path);
err:=closesocket(sock);
if err=0 then
WriteLog(now,'编号为:'+Fid+' 的对应SOCKET释放成功!',path);
end
else
begin
WriteLog(now,'编号为:'+Fid+' 的对应SOCKET连接通讯主机成功!',path);
exit;
end;
end;
WSAcleanup;
end;
///********************************************
WSAAsyncSelect(sock, handle, WM_SOCK, FD_READ );
//将消息帮定,但是因为没有窗体,第二个参数到底怎样写呀。
//它的值取谁的 HANDLE
//*******************************************
end;
destructor TTSocketThread.Destroy;
begin
WriteLog(now,'ID:'+Ftelid+'通讯结束!',path);
inherited;
end;
procedure TTSocketThread.Execute;
var
len:integer;
begin
//FreeOnTerminate:=true;
senddate;
end;
procedure TTSocketThread.ReadData(var Message: TMessage);
var
flen: integer;
Event: word;
RecvBuff:array [0..1024] of char;
RecvS:string;
begin
flen:=sizeof(FSockAddrIn);
FSockAddrIn.SIn_Port := htons(strtoint(Fport));
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
recvfrom(sock,RecvBuff,sizeof(RecvBuff),0,FSockAddrIn,flen);
end;
end;
procedure TTSocketThread.senddate;
var
ret,len:integer;
s:string;
psendchar;
begin
s:='01,'+Fid+';';
len:=length(s);
psend:=stralloc(len);
Strpcopy(Psend,S);
ret:=send(sock,psend^,len,0);
WriteLog(now,s,path);
if ret=SOCKET_ERROR then
WriteLog(now,'发送 '+s+'失败',path);
end;
end.
请大家帮我看一下,我程序有什么问题?能够发送,服务端接受也正确。但是这个线程不能拦截服务端发送来的消息。收不到。
我想问下大家,创建SOCKET的时候,
addr.sin_family:=PF_INET;
addr.sin_port:=htons(strtoint(FPort));
addr.sin_addr.S_addr:=inet_addr(pchar(FIp));
err:=WSASTARTUP($101,TempWSAData);
这个里面对应的IP,PORT是远程服务端的IP,PORT吧?
那我线程中创建的SOCKET的自己 的IP,PORT是在那设置?我不太清楚API创建SOCKET的关系。谢谢。