socket多用户连接求助

cxrcool 2011-07-23 05:01:15
小弟正在做一个flash为客户端,php为服务端的socket小程序

现在出现一个问题flash成功连接服务端后!一切都能正常通信

但是不能多用户连接服务端(比如我打开两个flash,第二就会连接不上)

求助php socket是否能解决多用户连接的问题


望高手相助
...全文
1257 60 打赏 收藏 转发到动态 举报
写回复
用AI写文章
60 条回复
切换为时间正序
请发表友善的回复…
发表回复
游戏码仔 2013-10-07
  • 打赏
  • 举报
回复
引用 15 楼 cxrcool 的回复:
非常感谢大家,已经可以达到多人在线了 感觉即时性也非常的好 谢谢maquan和BooJS 结贴后还能继续聊天吗? 还想跟你们聊聊呢?
你好 请问你是怎么实现多人在线的?是用php的socket吗? 我现在也遇到了这个问题! 我的是用cli执行一个socket.php 然后执行一个swf可以连接数据 返回数据。但是两个一起就不行了,就算连接一个swf,当我把这个swf关掉后再打开的话服务器就返回不了数据了! 可以分享一下你的经验吗? 提点一下我! 谢谢!
lxq73061 2011-11-05
  • 打赏
  • 举报
回复
我也在开发socket方面的东西
maquan 2011-07-30
  • 打赏
  • 举报
回复
[Quote=引用 49 楼 cxrcool 的回复:]
我做的这个其实就是对一个ip的不同端口进行广播呀
应该是可以办到的吧
如果无法办到就真的只能维护一个用户使用的端口表了
[/Quote]
我没太看懂你的问题所在。

据我的理解,UDP 广播包只能发给同网段所有 IP 的同一个端口,而不能发给一个 IP 的多个端口

你不用让每个接收方使用不同端口,那样非乱套不可。就让它们在同一个固定端口做监听,收到的东西如果不是发给自己的,则忽略掉,重新监听。

不过我突然相当一个问题,这样用广播包的话,同一个服务器上的其它网站,甚至是同一个机房的其它服务器,是不是都能收到这些数据包了?……看来在数据安全方面还得注意一下,hehe
cxrcool 2011-07-30
  • 打赏
  • 举报
回复
确实如此只要开放了udp端口

外网直接使用255.255.255.255也是可以广播成功的
cxrcool 2011-07-30
  • 打赏
  • 举报
回复
我再试试255.255.255.255呢
呵呵
cxrcool 2011-07-30
  • 打赏
  • 举报
回复
结贴,问题已经完全解决!
感谢maquan和其他网友的热心帮助!

本该多给分的,但是小弟确实是没有积分了
maquan 2011-07-30
  • 打赏
  • 举报
回复
[Quote=引用 47 楼 cxrcool 的回复:]
有道理
计算一下外网的广播地址测试一下
广播地址要有子网掩码才能算啊
还得问问服务商,只有IP貌似算不了
[/Quote]
学习了一下“百度百科:广播地址”的知识,里面提到“有限广播”和“直接广播”。

你这种应用背景,应该是用“有限广播”,那么也就不必要去算什么广播地址了,直接用 255.255.255.255 就好了。


————————————————————————————————
基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
cxrcool 2011-07-30
  • 打赏
  • 举报
回复
防火墙要添加一个开放的udp端口才行

也就是我程序里面进行广播的那个端口
cxrcool 2011-07-30
  • 打赏
  • 举报
回复
哈哈广播成功了

防火墙的问题设置下就好了!!!

我的广播码没有计算错误
maquan 2011-07-29
  • 打赏
  • 举报
回复
这个我也不是很清楚。

UDP 广播包跟普通的 UDP 包一个很明显的区别就是“目标 IP 地址不同”。作为“监听 UDP 包”的 socket,从物理上讲,它肯定能“感知”到广播和非广播的 UDP 包,但它会不会“接收”广播包呢?如果你已经把这个 socket 设成“广播”型了,那肯定就没问题了,但如果不设置呢?它会不会拒收呢?

我觉得这个不好说,可能跟具体的系统实现有关吧。虽然实际使用时不写也可以,但我总觉得写上更安全。
cxrcool 2011-07-29
  • 打赏
  • 举报
回复
非常感谢
已经测试成功
现在返回去看SO_REUSEADDR的解释Reports whether local addresses can be reused.
才恍然大悟,“是否可重复使用本地地址”
设置了这个option过后就不会再出现bind时提醒一个IP一个端口只能被建立一个连接了

刚测试发现
recvfrom.phpl里面不用加这句也成功
socket_set_option( $socket, SOL_SOCKET, SO_BROADCAST, 1 );

我认为可以删除,因为广播的页面是sendto.php,recvfrom.php只需要可重复使用本地地址和端口就行了

是这样吗?
maquan 2011-07-29
  • 打赏
  • 举报
回复
昨天晚上心血来潮,写了一段 UDP 广播通信的程序,正好可以供你参考 :)

recvfrom.php

<?php
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

$socket = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
socket_set_option( $socket, SOL_SOCKET, SO_BROADCAST, 1 );
socket_set_option( $socket, SOL_SOCKET, SO_REUSEADDR, 1 );
$result = socket_bind( $socket, '0.0.0.0', 9999 );

$addr = '';
$port = 0;
$result = socket_recvfrom( $socket, $buf, 10240, 0, $addr, $port );
socket_close($socket);

echo "recvfrom: [({$result}){$buf}] from [{$addr}:{$port}]";


sendto.php

<?php
$socket = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
socket_set_option( $socket, SOL_SOCKET, SO_BROADCAST, 1 );

$msg = date('Y-n-j H:i:s');
$len = strlen( $msg );
$result = socket_sendto( $socket, $msg, $len, 0, '255.255.255.255', 9999 );
socket_close( $socket );

echo "sendto: [({$result}){$msg}]";


以上两个 PHP 程序,recvfrom.php 可以用多个浏览器窗口分别发送请求,都会处在等待状态,然后再用一个浏览器窗口发送 sendto.php 的请求,前面的几个浏览器窗口就同时得到结果了。


————————————————————————————————
基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
cxrcool 2011-07-29
  • 打赏
  • 举报
回复
还是不行
socket_sendto函数的端口参数不能为空的话接收端就收不到信息,也就是说不能一次性send信息给所有线上的端口

socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1); 应该是写在接收端吧,但是写了也不行

你能写个例子给我吗?
cxrcool 2011-07-29
  • 打赏
  • 举报
回复
尝试了一下不行
帮我看看广播地址是不是算错了


IP 地址: 123.183.215.45
子网掩码: 255.255.255.128
默认网关: 123.183.215.1

我算出来是
123.183.215.127
cxrcool 2011-07-29
  • 打赏
  • 举报
回复
我做的这个其实就是对一个ip的不同端口进行广播呀

应该是可以办到的吧

如果无法办到就真的只能维护一个用户使用的端口表了
maquan 2011-07-29
  • 打赏
  • 举报
回复
不知道我理解得对不对,广播(broadcast)仅限于局域网内,即一个网段。要出外网的话,就是多播(multicast)了,需要路由器配合。
cxrcool 2011-07-29
  • 打赏
  • 举报
回复
有道理
计算一下外网的广播地址测试一下

广播地址要有子网掩码才能算啊

还得问问服务商,只有IP貌似算不了
maquan 2011-07-28
  • 打赏
  • 举报
回复
用 UDP 广播,具体用法你查一下资料吧。
cxrcool 2011-07-28
  • 打赏
  • 举报
回复
我运用了你的方法尝试,发现一个问题

每个端口只能创建一个套接字
如果我使用随机端口的话socket_sendto就不会知道目前有哪些端口需要发送了

我是否需要维护一个当前在线的端口表?是保存到数据库比较好,还是存为文件模式呢?
maquan 2011-07-28
  • 打赏
  • 举报
回复
再试试 socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);
加载更多回复(39)

21,887

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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