gsging
- UID
- 14169
- 帖子
- 179
- 积分
- 411
- 在线时间
- 1 天 19 小时
|
1#
gsging 发表于 2007-12-24 23:58
多线程之间共享socket问题
最近想用Win32::GUI聊天客户端软件.
当成功登录服务器后,派生出一个线程,用来专门收数据,主线程用来发送数据.
以下是节选出的主要代码,里面可能缺少了某些工具方法.
#!c:\perl\bin\perl.exe -w
use strict;
use Win32::GUI;
use threads;
use threads::shared;
use PerlChat::Chat;
use PerlChat::Config;
use PerlChat::Utils;
#初始化聊天类
my $config = getConfig("conf/config.conf");
my $chat = PerlChat::Chat->spawn($config->{ip},$config->{port});
my $mainWin = new Win32::GUI::Window(
-name => 'mainWin',
-text => '51GG',
-size => [ $s_Main->{w}, $s_Main->{h} ],
-onResize => \&mainWinResize,
-onMinimize => sub { 1 },
-onMaximize => sub { 1 },
-onTerminate => \&mainWinClose,
);
$mainWin->AddTextfield(
-name => 'Username',
-pos => [ $s_Login->{x} + 55, $s_Login->{y} + 20 ],
-size => [ 120, 20 ],
-prompt => [ "用户名:", -45 ],
);
$mainWin->AddTextfield(
-name => 'Password',
-pos => [ $s_Login->{x} + 55, $s_Login->{y} + 40 ],
-size => [ 120, 20 ],
-password => 1,
-prompt => [ "密 码:", -45 ],
);
$mainWin->AddButton(
-name => 'LoginServer',
-pos => [ $s_Login->{x} + 50, $s_Login->{y} + 70 ],
-title => '登录',
-onClick => \&LoginServer,
);
$mainWin->AddButton(
-name => 'LogoutServer',
-pos => [ $s_Login->{x} + 100, $s_Login->{y} + 70 ],
-title => '注销',
-disabled => 1,
-onClick => \&LogoutServer,
);
#主循环
$mainWin->Show();
Win32::GUI::Dialog();
sub LoginServer{
$chat = PerlChat::Chat->spawn($config->{ip},$config->{port}) unless ($chat->{dp});
my ($username,$password) = ($mainWin->{Username}->Text(),$mainWin->{Password}->Text());
my $loginStr = makeLoginStr($username,$password);
$mainWin->MessageBox('登录信息发送失败,请重新启动本程序,点击"确定"关闭本程序','错误',MB_OK | MB_ICONERROR) and return -1 unless ($chat->send_data($loginStr) == 0);
my $ret = $chat->recv_data(1);
$mainWin->MessageBox('系统繁忙,登录失败,请重新启动本程序,点击"确定"关闭本程序','错误',MB_OK | MB_ICONERROR) and return -1 unless ($ret == 1);
my $threadRecvMsg = threads->create(sub {$chat->recv_data($mainWin);});
$threadRecvMsg->detach();
}
sub LogoutServer
{
my $logoutStr = "~2~" . $chat->{'uin'} . "~100~200~1~0~0";
$logoutStr = ( length($logoutStr) - 1 ) . $logoutStr;
$chat->{'dp'}
->send_data( $chat->{'sock'},$logoutStr);
$chat->{'dp'}->close_socket( $chat->{'sock'} );
}
__END__
|
但是遇到一个问题是,当派生出一个新线程后,就只能收数据了,主线程不能发数据了.因为收数据和发数据需要共用一个socket,我把这个socket存在一个聊天对象中.
这时候就有个在不同线程间共享socket的问题.
我用threads::shared模块的share方法来共享数据,
在程序的最开始想直接共享$chat这个对象.但是同样只能收不能发.
我尝试在login方法中加入只对$chat->{'socket'}共享,但是Perl提示:Cannot share globs yet.
不知道我有没有描述清楚,我估计原因可能是socket没有共享.所以导致只能收不能发.
请问这种情况应该怎样解决.谢谢.
如果我哪个地方没有描述清楚我会补上.
|