我不知道你说的管道是什么东东。如果你要做聊天室这样的东西,可以参考以下代码。一般把可能阻塞的读操作放在另外的线程里,如果要向Socket里写东西,随时都可以直接写。 每个Client对象创建时起一个线程,不断读取客户端发来的东西,然后把读取的内容交给Server,由Server在每个Client上(因为Server保存了所有Client的列表)调用send 方法发送出去。//for the server class Server{ ServerSocket s; List clients; //hold all clients
void fun(){ while(true){ Socket socket = s.accept(); Client c = new Client(this, socket); clients.add(c); } }
void broadcast(String s){ for each c in clients{ c.send(s); } } }//one instance for each client class Client implements Runnable{ Socket s; Server server; BufferedReader reader; PrintWriter writer;
你的din.available()是一致连的,应该是中返回true。
to :义水寒:
可是那这个新线程和老线程还要互相通讯,因为还得互相传数据呀,这就陷入一个悖论了。
我现在的run()已经多线程了。
整个系统是这样的:
Applet请求Socket服务,与服务程序建立连接后,服务主线程spawn一个子线程去和该客户端连接。主线程同时listen新的请求。每个子线程与主线程间是靠管道通讯。每个子线程既要和客户端保持链路,又要和主线程通讯。也就是while(1)中作的事情了。
while(1)
{
checkNew();//与主线程联络,看有没有新的信息发给它。用管道实现。
din.readLine();//与客户端联络,看由否新的信息。
}
这样的话,din.readLine()会阻塞住,没法执行checkNew()。
或者你自己改一下java 1.4的NIO让它在1.3下好用不过个人觉得你的设计是不是有些问题啊,看能不能改一下
void callback2();
和主线程通信的线程:
while(true){
checkNew();
callback1();
}
和客户端通信的线程:
while(true){
din.readLine();
callback2();
}
即使再多的线程,二者间的通讯不也得用管道通讯吗?
to farandfaraway(遥远) :
这样设完后,是这样写吗?
socketServer.setSoTimeout(100); //100毫秒
while(1)
{
checkNew();//与主线程联络,看有没有新的信息发给它。用管道实现。
try{
din.readLine();//与客户端联络,看由否新的信息。
}
catch (TimeoutException e)//捕捉超时
{
continue;
}
catch (Exception e)
{
//报错
}
}
对吗?
to eureka0891(迷茫中...):我想做一个类似聊天室的东西,但不是每次客户端请求,而是每个客户端对应一个子线程服务,服务子线程收到它的消息后传递给主线程,再由主线程广播给其他子线程,这样子线程的工作中既包含与客户端的联系,又必须发送/接收主线程的消息。有什么别的方法吗?
每个Client对象创建时起一个线程,不断读取客户端发来的东西,然后把读取的内容交给Server,由Server在每个Client上(因为Server保存了所有Client的列表)调用send 方法发送出去。//for the server
class Server{
ServerSocket s;
List clients; //hold all clients
void fun(){
while(true){
Socket socket = s.accept();
Client c = new Client(this, socket);
clients.add(c);
}
}
void broadcast(String s){
for each c in clients{
c.send(s);
}
}
}//one instance for each client
class Client implements Runnable{
Socket s;
Server server;
BufferedReader reader;
PrintWriter writer;
Client(Server server, Socket s){
this.s = s;
this.server = server;
//create reader from socket
//create writer from socket
new Thread(this).start();
}
public void run(){
while(true){
String line = reader.readLine();
server.broadcast();
}
}
public void send(String line){
writer.println(line);
}
}
管道是指的多线程间的通讯,你程序里的client相当于我的服务程序的子线程,而你的Server相当于我的服务程序的主线程,但问题是你的client程序还要接收真正的从客户端的连接。就是在你的所谓client程序run()中:
while(true)
{
String line=reder.readLine();
server.broadcast();
readFromRealClient();//通常是阻塞的
}
while(true){
String line = reader.readLine();
server.broadcast(line);
}
}
我觉得我给你的代码完全能实现你的功能了。
Server类的broadcast方法就是用来把一个子线程收到的消息发送到所有客户端去的。你是不是把问题想得太复杂了?
在不同线程间通信时,回调方法是最简洁、有效的选择。broadcast就是Server提供给Client的回调方法。Client线程在readLine上阻塞,阻塞的时候并不妨碍它的send方法被Server的broadcast调用。你所说的readFromRealClient是不必要的,readLine就是做这个的。
给你画个图吧
Server
|
|
-------------
| |
| |
Client1 Client2
| |
| |
| |
Applet1 Applet2