有关创建线程与网络进行通讯的方法(50分)

  • 主题发起人 主题发起人 tuiger1
  • 开始时间 开始时间
T

tuiger1

Unregistered / Unconfirmed
GUEST, unregistred user!
大家好,我不知道如何在创建的线程里使用socket与网络服务器通讯,是使用clientsocket
么?我在编线程程序前用窗口做了一下,使用了clientsocket控件,在connect过程很顺利
发出消息,在read过程中很顺利地得到消息,而在线程程序中该怎样定义相应的socket,很
怎样通讯,我就不知道了,请大家帮助!
最好能写几句,让我能明白,谢谢了!
 
在线程中声明:socket1:Tclientsoecket;
然后:socket1:=Tclientsocket.create(nil);
socket1.port:=21;
socket1.host:=主机IP地址
按照上面的方式将socket1设成异步模式
socket1.sendtext:='testdata';
在线程中要设定消息循环,来等待SERVER返回的消息
(详细例程我下个星期给你贴出来,不过记得要给我加分呀)
 
你也太小气了,这么点分!
 
一般Socket用在线程中是将它的ClientType = ctBlock,如果是非阻塞,那将TClientSocket
加在线程中没有什么意义,因为非阻塞是在消息驱动的,它不会阻塞主线程的运作。
而在阻塞 + 线程中,它的onRead/OnWrite事件就不能用了,你在线程中的Execute过程中
进行Socket数据的等待/read/write.然后将数据通过消息或什么方式传给处理过程
constructor TMyThread.Create(AHandle: THandle);
begin
FreeOnTerminate := True;
FHandle := Form1.CLientSocket1.Socket.SocketHandle;
inherited Create(False);
end;

procedure TMyThread.Execute;
begin
//winsock.select等待,ret := recv(FHandle, buffer, sizeof(buffer), Flag);
//flag= 0将
//缓存数据取出Count个字节到buffer,并清空它,flag=2,copy数据,不清空
//如果ret不等于count,出错了。
//也可以用Form1.ClientSOcket.Socket.ReceiveBuf(Buffer, sizeof(buffer)

//SConnect WSACreateEvent, WSAEventSelect, WaitFor, WSAResetEvent,WSACloseEvent函数

取出数据后,将它Buffer地址发送给处理主窗体。Loop,当ClientSOcket.Connected = True
end;
 
有人说要帖东东!赶紧来学习
 
帖什么东东啊??谁啊?
 
unit threadSocket3;
interface
uses
Classes,ScktComp,sysutils,Graphics,windows,messages,ExtCtrls,forms,decode,Controls,BatchRefresh;
type
tcsocket3 = class(TThread)
private
cskccr:Tclientsocket;
{ Private declarations }
protected
procedure write_canves;
proceduredo
connect(Sender: TObject;Socket: TCustomWinSocket);
proceduredo
Error(Sender: TObject;Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
proceduredo
Read(Sender: TObject;Socket: TCustomWinSocket);
procedure Execute;
override;
public
end;
type
TTimeForm = class inheritsFrom:TForm;
private
public
timecount:Ttimer;
procedure TimeOnTimer(Sender:TObject);
end;
var
CmdStr:string;
DataStr:string;
AddrStr:string;
typeid:integer;
msg:tagMSG;
net_str:string;//网络状态提示字符串;
readerserial:string;//读卡器序列号字符串
time_str:integer;
pcmname:string;
PrintStr:string;
timecount:Ttimer;
k:integer;
W_tmperr,W_tmprd,W_tmptm:integer;
function labfaile3(typeid:integer;net_str:string):string;//提示下载失败
function labsucc3(typeid:integer):string;//提示下载成功
procedure Receive_comm3(ReccmdStr:string);
//接收命令字符串过程
procedure Receive_data3(RecDataStr:string);//接收数据字符串过程
procedure Recive_addr3(RecAddr:string);//接收IP地址字符串过程
procedure recive_type3(rectype:integer);//接收下载项目类型
procedure recive_name3(reader_name:string);//接收读卡器序名称
procedure recive_pcmid3(pcm_ID:integer);//取得PCM的ID
procedure net_messages3(net_code:integer);//网络状况信息提示;
procedure checkvalue3();
procedure time_count3();//计时器功能,如果超过时间未能接收到返回确认包,即强行结束线程
implementation
var
TTF : TTimeForm;
procedure checkvalue3();
begin
k:=0;
end;
procedure time_count3();
begin
TTF := TTimeForm.Create;
TTF.timecount :=TTimer.Create(nil);
TTF.timecount.Interval:=20000;
TTF.timecount.Enabled:=true;
TTF.timecount.OnTimer := TTF.TimeOnTimer;

end;

procedure TTimeForm.TimeOnTimer(Sender:TObject);
begin
W_tmptm := W_tmptm+TTf.timecount.Interval;
end;

procedure TCsocket3.write_canves;
var
tmp:string;
begin
tmp:=PrintStr;
FrmBatchRefresh.rededit.Lines.Add(tmp);
end;
procedure Receive_comm3(ReccmdStr:string);
//接收命令字符串
begin
CmdStr:=ReccmdStr;
end;

procedure Receive_data3(RecDataStr:string);//接收数据字符串
begin
DataStr:=RecDataStr;
end;

procedure Recive_addr3(RecAddr:string);//接收IP地址
begin
AddrStr:=trim(RecAddr);
end;

procedure recive_type3(rectype:integer);//接收下载项目类型
begin
typeid:=rectype;
end;

procedure recive_pcmid3(pcm_id:integer);
begin
pcmname:=inttostr(pcm_id);
end;

procedure recive_name3(reader_name:string);
begin
readerserial:=reader_name;
end;

{连接事件}
procedure TCsocket3.doconnect(Sender: TObject;Socket: TCustomWinSocket);
begin
Socket.SendText(CmdStr);//命令包
Socket.SendText(DataStr);//数据抱
end;
{错误处理事件}
procedure TCsocket3.doError(Sender: TObject;Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
net_messages3(errorcode);
FrmBatchRefresh.rededit.SelAttributes.Color:=clyellow;
PrintStr:=labfaile3(typeid,net_str);
synchronize(write_canves);
errorcode:=0;
w_tmperr:=1;

end;
{读取文本事件}
procedure TCsocket3.doRead(Sender: TObject;Socket: TCustomWinSocket);
var
FStr:string;
begin
FStr:=Socket.ReceiveText;
if Copy(Fstr,1,2)='DT' then
begin
hid1:=1;
PrintStr:=labsucc3(typeid);
FrmBatchRefresh.rededit.SelAttributes.Color:=claqua;
synchronize(write_canves);
w_tmprd:=1;
end;
end;

procedure TCsocket3.Execute;
begin
W_tmperr:=0;
W_tmprd:=0;
W_tmptm:=0;
freeonterminate:=true;
cskCCR:=Tclientsocket.Create(nil);
cskCCR.Address:=AddrStr;
cskCCR.Port:=8001;
cskCCR.ClientType:=ctNonBlocking;
cskCCR.OnConnect:=doconnect;
cskCCR.OnError:=doError;
cskCCR.OnRead :=doread;
cskCCR.Active:=true;
hid1:=0;
checkvalue3();
time_count3();
while (W_tmperr <> 1) and (W_tmprd <> 1) and (W_tmptm <= 20000)do
begin
application.ProcessMessages;
end;
TTf.timecount.Enabled:=false;
TTF.timecount.Free;
if W_tmptm > 20000 then
begin
PrintStr := '传输超时';
FrmBatchRefresh.rededit.SelAttributes.Color:=claqua;
synchronize(write_canves);
end;
hid:=1;
//信号变量,标识线程是否结束0:未结束 1:结束 声明人:王志伟
cskCCR.Close;
cskCCR.Free;
terminate;
end;

function labsucc3(typeid:integer):string;
var
i:integer;
begin
i:=typeid;
case i of
11://门禁机优先序列
begin
result:='向'+pcmname+'号PCM下发'+trim(readerserial)+'的'+'门禁机配置文件成功';
end;
end;
end;
function labfaile3(typeid:integer;net_str:string):string;
var
i:integer;
netstr:string;
begin
i:=typeid;
case i of
11://门禁机优先序列
begin
result:=netstr+' '+'向'+pcmname+'号PCM下发'+trim(readerserial)+'的'+'门禁机配置文件失败';
end;
end;
end;
procedure net_messages3(net_code:integer);
begin
case net_code of
10004:begin
net_str:='操作被终止';
end;
10013:begin
net_str:='访问被拒绝';
end;
10024:begin
net_str:='打开太多的SOCKET';
end;
10048:begin
net_str:='地址已经被使用';
end;
10049:begin
net_str:='设置地址失败';
end;
10050:begin
net_str:='网络关闭';
end;
10051:begin
net_str:='网络不可达';
end;
10052:begin
net_str:='网络被重置';
end;
10055:begin
net_str:='缓冲不足';
end;
10057:begin
net_str:='SOCKET未连接';
end;
10058:begin
net_str:='SOCKET已经关闭';
end;
10060:begin
net_str:='连接超时';
end;
10061:begin
net_str:='连接被拒绝';
end;
10064:begin
net_str:='主机已经关机';
end;
10065:begin
net_str:=' 找不到路由';
end;
10067:begin
net_str:='进程太多';
end;
11001:begin
net_str:='找不到主机';
end
else
net_str:='其他原因导致网络错误';
end;
end;

end.
[:)][:)][:)]
 
后退
顶部