高手请帮忙,关于TClientSocket方面疑难杂症!!!!

tsk 2005-08-22 05:19:22
我在编写客户端与服务器端通信时,用到ClientSocket和ServerSocket控件,采用的是非阻塞通信!
服务器端 IP: 192.168.0.1 端口号:5678
首先写义全局变量:
int ConnectState=1; //此变量是作为成功建立Socket时的标志,初始为1表示未连接.
//----------------------------------------------------------
Socket初始化函数原型:
InitSocket(AnsiString ServerIP,int Port)
{
ClientSocket1->Host=ServerIP; //服务器端IP
ClientSocket1->Port=Port; //服务器端端口号
ClientSocket1->Active=true; //激活连接
}
//----------------------------------------------------------
在 ClientSocket控件的OnConnect()事件中写入下面代码:
void __fastcall TForm1::ClientSocketConnect(TObject *Sender,
TCustomWinSocket *Socket)
{
ConnectState=0; //表示双方成功建立连接
}
//----------------------------------------------------------
在窗体上放置Button按钮,执行下面代码:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
InitSocket("192.168.0.1",5678);
if(ConnectState==0)//如果是连接是成功的.
{
Login("用户名","密码"); //登录到服务器用的函数
}

}
//----------------------------------------------------------
我的问题是:
在Button1Click函数里,if内的语句始终得不到执行,当Button1Click执行后,
才会产生OnConnect()事件,这是为什么,我在执行InitSocket()函数后,
Sleep(1000); 也不管用,
请问怎样更改代码,才能满足我的要求? 谢谢各位!
...全文
792 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
pp616 2006-05-11
  • 打赏
  • 举报
回复
那可能是TServerSocket的代码没有去捕捉这个错误。
自己用Socket sdk写的话就完全由自己控制了。
meikeer 2006-05-11
  • 打赏
  • 举报
回复
当我把Server端网线拔掉,还是出现10053错误!这个偶也没有解决,顶一下
jandyking 2006-05-03
  • 打赏
  • 举报
回复
学习一下
koc2030 2006-04-07
  • 打赏
  • 举报
回复
借用一下!
为什么我用TServerSocket
在OnClientError中加入了ErrorCode=0;
当我把Server端网线拔掉,还是出现10053错误!
OnClientError根本就没有触发!
tsk 2006-04-07
  • 打赏
  • 举报
回复
TO Leighf:
当Socket连接失败会产生 OnError 表面有socket出错代码,比如10061 10038 10053
把它取出来,再设 ErrorCode=0;
Leighf 2006-03-03
  • 打赏
  • 举报
回复
在连接失败后,如何捕捉异常呢?
OnError事件里是否该写点什么呢,望指点……
tsk 2006-02-27
  • 打赏
  • 举报
回复
好的,学习
wizardqi 2005-11-08
  • 打赏
  • 举报
回复
//哦Sorry,忘了这里是BCB区了,平时来得少,现在把所有的语句翻译后如下:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
ServerSocket1->Port=1981;
ServerSocket1->Active=true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
ClientSocket1->Host="127.0.0.1";
ClientSocket1->Port=1981;
ClientSocket1->Active=true;
if(ClientSocket1->Active)ShowMessage("Direct test ok!");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Connect(TObject *Sender,
TCustomWinSocket *Socket)
{
ShowMessage("In Connect event test ok!");
}
//---------------------------------------------------------------------------
wizardqi 2005-11-05
  • 打赏
  • 举报
回复
(*
to chenzhou851025(青竹园主) ,
把login函数放在onconnect函数里和楼主的想法有什么冲突吗,我觉的没有冲突呀.可以试一下吧.
你看看如下的代码,并运行看看结果就明白我的意思了。
“在非阻塞方式下,网络事件是靠消息机制维护的,而按钮本身的单击事件也是一个消息,在这个消息处理过程没有执行完毕前的瞬间是不会有其他低优先级的消息被处理的,因此在连接事件中进行登陆认证是比较合适的。当然,你可以把连接和认证放在不同的按钮里触发也是个方法,这样可以给网络消息触发网络事件提供间隙,可以使OnConnect事件被触发。”
*)

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ScktComp, StdCtrls;

type
TForm1 = class(TForm)
ClientSocket1: TClientSocket;
ServerSocket1: TServerSocket;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
with ServerSocket1 do
begin
Port:=1981;
Active:=True;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
with ClientSocket1 do
begin
Host:='127.0.0.1';
Port:=1981;
Active:=True;
if Active then ShowMessage('ok');
end;
end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
ShowMessage('Connect ok');
end;

end.
asdfg014 2005-11-04
  • 打赏
  • 举报
回复
用WINAPI来写~想怎么样就能怎么样了
chenzhou851025 2005-11-03
  • 打赏
  • 举报
回复
把login函数放在onconnect函数里和楼主的想法有什么冲突吗,我觉的没有冲突呀.可以试一下吧
wizardqi 2005-11-02
  • 打赏
  • 举报
回复
当网络连接建立成功后.
wsb01071054 2005-10-30
  • 打赏
  • 举报
回复
请问一下 OnConnect事件是什么时候触发。
wizardqi 2005-10-20
  • 打赏
  • 举报
回复
在非阻塞方式下,网络事件是靠消息机制维护的,而按钮本身的单击事件也是一个消息,在这个消息处理过程没有执行完毕前的瞬间是不会有其他低优先级的消息被处理的,因此在连接事件中进行登陆认证是比较合适的。当然,你可以把连接和认证放在不同的按钮里触发也是个方法,这样可以给网络消息触发网络事件提供间隙,可以使OnConnect事件被触发。
xibingwuqing 2005-10-19
  • 打赏
  • 举报
回复
学习
yesry 2005-10-19
  • 打赏
  • 举报
回复
楼上广告太多。
zsp5869999 2005-10-14
  • 打赏
  • 举报
回复
www.51merit.com
上有

WINSOCK LAN传文件(倚天篇)
WINSOCK史上最经典的例子(屠龙篇)
的源代码!
qq:42872272

同样,还有高速缓存,内存数据库的做法!
tsk 2005-09-16
  • 打赏
  • 举报
回复
还没来得及试,先顶一下!
iec 2005-08-31
  • 打赏
  • 举报
回复
可以这样做:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
InitSocket("192.168.0.1",5678); //初始化Socket
PostMessage(MainFrm->Handle,WM_USER+101,NULL,NULL);

}
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_USER+101, TMsg, Login)
END_MESSAGE_MAP(TForm)
void TMainFrm::Login(TMsg msg)
{
while(ConnectState==1)
{
Application->ProcessMessages();
}
Login("用户名","密码"); //登录到服务器用的函数
}
jishiping 2005-08-30
  • 打赏
  • 举报
回复
使用非阻塞,是通过消息驱动的。如果你直接写成:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
InitSocket("192.168.0.1",5678);
if (ConnectState==0)
{
Login("用户名","密码"); //登录到服务器用的函数
}
}
你调用InitSocket后,就相当于你电话给人家,你只是拨号了,人家还没有接听,此时电话还没有接通。如果你使用上面的循环,不断调用 Application->ProcessMessages(); 那么就是让程序去处理消息,这样Socket才可能变成接通的。

但是你上面的代码,循环的判断条件是ConnectState==1,那么你是在哪儿将ConnectState设为0的呢?所以如果你没有在OnConnect中写代码,那么你这儿的代码
while(ConnectState==1)
{
Application->ProcessMessages();
}
就变成死循环了。
加载更多回复(7)

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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