请教用socket通信的基本问题!

villagehead 2003-01-07 10:00:54
请问程序中用socket通讯的话,
(服务器端或是客户端)是不是必须有inputstream和outputstream?

也就是说这两个流是不是必须要都出现在通讯的过程中的?
如果服务器端没有outputstream的话,
客户端是不是就要进入“阻塞”状态死等?

那要是不想让服务器马上回信,而是等待一会在回的话,
服务器端应该用什么样的方法而不用让客户端白等呢?

我是想编一个最最最最最最简单的基于socket的聊天室程序作为练习,
那么,我的服务器端的程序应该怎样做才能实现最基本的功能呢?
比如定时1-2秒向客户端发送数据等等。。

谢谢
...全文
45 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
sayo 2003-01-09
  • 打赏
  • 举报
回复
不用太复杂,先做着,会发现一些问题的

比如先做个单对单的聊天
sayo 2003-01-09
  • 打赏
  • 举报
回复
不是的

服务器端运行着针对每个客户的线程,每个线程都有自己的socket,当客户发送信息到自己的线程socket上,此线程从用户列表中找到谈话对方(也就是找到对方的用户类)将消息加入到对方的消息列表中,由其进行发送

服务器端客户线程的运行是这样的:
--产生,当用户登陆服务器时
--运行,
--接收用户的谈话请求
--定时到消息列表中察看是否有消息需要发送给客户
--消亡,当用户离线时
villagehead 2003-01-09
  • 打赏
  • 举报
回复
那么就是说:

1.在服务器端存储每个客户端发来的信息。
2.客户端定时从服务器端“取”出那些数据。

是这样的吗?
sayo 2003-01-09
  • 打赏
  • 举报
回复
至于服务器如何处理客户的消息,好像专业点的聊天室专门有算法进行处理,我不清楚,呵呵

还有,客户用一个类来表示
sayo 2003-01-09
  • 打赏
  • 举报
回复
客户列表中应该放置该客户对应的socket句柄啊,或者还有一些该客户所属的信息吧

其实不必让服务器来定时给客户端发信息,而让客户端发向服务器,服务器只响应这样的“空闲消息”,这样服务器的负担不会太重

villagehead 2003-01-09
  • 打赏
  • 举报
回复
那么服务器端要存储所有客户端发来的信息喽?

还有就是想问一下,服务器端怎么向每一个客户端发信息?
sayo 2003-01-09
  • 打赏
  • 举报
回复
最基本的功能

就是让两个客户端能够对话啊
服务器端起到中转的作用,那么服务器端应该维护一个在线的客户列表,当有客户请求时,从表中查找要对话的对方客户,并将对话消息转发给对方客户。

这里面要注意的问题:
--服务器端可能用多线程实现,那么就得注意线程安全了,特别是客户列表
--客户之间以及客户与服务器之间的对话,应该有比较好的组织形式,可以用XML来规格之如:
<from>sayo</from>
<to>villagehead</to>
<time>2003-1-9 10:00:00:000</time>

<content>Hello!</content>
(其实这样也比较容易以后的扩展)


这些也是根据我自己用vc做聊天室的经验,仅供参考
villagehead 2003-01-09
  • 打赏
  • 举报
回复
那些例子倒是应该挺好的,可是我还是有些看不大明白!

所以再推一下!

高手赐教呀!
sayo 2003-01-09
  • 打赏
  • 举报
回复
提示:
可以用Socket.getInputStream().available()来判断是否可以读取数据,而不用一直等待阻塞的socket,这样或许可以用一下模式来处理服务器端:
--服务器端不为每个用户提供两个线程(收、发)
--只提供两个线程(收、发)
--收线程循环遍历所有用户socket,有需要处理的进行接收处理,不需要处理则继续循环
--发线程循环所有用户信息列表,有需要处理的进行发送处理,不需要处理的则继续循环

考虑到效率问题,可以限制收、发线程各自的用户数量(如64个),用户数量超过64时,继续开线程进行处理

其实以上模式就是winsock中的事件重叠模式的翻版
sayo 2003-01-09
  • 打赏
  • 举报
回复
据说,jsdk1.4中有异步线程,这样就不用开那么多线程了

道听途说,我也不敢肯定
sayo 2003-01-09
  • 打赏
  • 举报
回复
那就每客户开两个线程了,一个专门收,一个专门发
收的线程接受用户输入,将用户输入转到对方用户信息列表中
发的线程从本用户的信息列表中获取信息,发往本用户

因此,注意服务器端的信息列表的线程安全管理
villagehead 2003-01-09
  • 打赏
  • 举报
回复
比如就是单对单的吧!

服务器写有一个线程去和相应的客户端的socket进行通信,
主程序(有server.accept();的程序)监听连接并开启服务器线程!
并把每个服务器端线程加入到一个Vector进行纪录。

服务器端和客户端通讯的程序是:
while(true){
String str = in.readLine();
if (str.equals("end")){
System.out.println("Client '" + this.getName() + "' Say: ByeBye");
break;
}else{
System.out.println("Client '" + this.getName() + "' Say: " + str);
out.println(this.getName() + "Say: " + str);
}
(这样写好象不对,这样的话只是能客户端对服务器进行通讯)

我现在开了两个客户端的socket,
客户端和服务器通讯的程序是:
try{
//get keyboard input
String strValue = input.readLine();

while(!strValue.equals("end")){
//send message to server
out.println(strValue);

//get message from server
String str = in.readLine();

//show
System.out.println(str);

//get keyboard input
strValue=input.readLine();
}
out.println("end");
}catch(IOException ioe){
ioe.printStackTrace();
}finally{
System.out.println("closing...");
try{
socket.close();
}catch(IOException ioe){
ioe.printStackTrace();
}

}

那末我第一个socket发出的信息,
怎么经过服务器发送到另一个客户端的socket呢?

我的问题是,
socket的input和output是要配对的
(我是这么理解的,也不知道对不对),
那么,在第一个client-socket发送消息之后,
它必然会等待一个inputstream的,
这时应该怎么处理对应于这个client-socket的这个服务线程里的outputstream,来对应客户端的inputstream??

还有就是怎么让另一个服务器端发送这条消息给另一个客户端?

是把记录服务端线程的变量定义为public static的,
然后在服务器端发送吗?


我理解能力比较差,请多原谅!



秋风ss落叶 2003-01-07
  • 打赏
  • 举报
回复
www.wrox.com
下载beginning java network programming

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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