public void go() {
try {
ss = new ServerSocket(8888);
while (true) {
Socket s = ss.accept();
examThread ex = new examThread(s);
ex.start();
}
} catch (IOException e) {
e.printStackTrace();
}
} class examThread extends Thread {
private Socket s; public examThread(Socket s) {
this.s = s;
} public void run() {
BufferedReader br = null;
PrintWriter pw = null;
try {
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str = null;
while (true) {
str = br.readLine();
/*while(str==null){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}*/
//System.out.println(str);
if (str.charAt(0) == '@') {
Set<String> set = stu.keySet();
boolean flag = false;
for (String str1 : set) {
if (str1.equals(str.split(":")[1].trim())
&& stu.get(str1).equals(
str.split(":")[2].trim())) {
flag = true;
pw = new PrintWriter(s.getOutputStream());
pw.println("true");
pw.flush();
 break;
}
}
if (!flag) {
pw = new PrintWriter(s.getOutputStream());
pw.println("false");
pw.flush();
}
} else if (str!=null&&str.equals("ready")) {
System.out.println(111);
for (String st : kemu) {
pw = new PrintWriter(s.getOutputStream());
pw.println(st);
pw.flush();
}
pw.println("#over#");
pw.flush();
System.out.println(222);
}
  } } catch (IOException e) {
e.printStackTrace();
} finally {
try {s.close();} catch (IOException e1) {}
if (pw != null)
pw.close();
if (br != null)
try {
br.close();
} catch (Exception e1) {
}
} }
在进入run方法中的While循环后,readline不会等待下一次输入而是while一直在循环,但是下面的这个程序,一样的多线程结构,但程序到readline的时候却阻塞等待下一次有效输入,不明白怎么写,还有希望大家给介绍一下Java socket通讯的阻塞和非阻塞模式
public void go(){
while(true){
try {
Socket s=ss.accept();
sockets.add(s);
new ChatRoomServerThread(s).start();

} catch (IOException e) {
e.printStackTrace();
}
}
}


public static void main(String[] args){
ChatRoomServer crc=new ChatRoomServer();
crc.go();
}

class ChatRoomServerThread extends Thread{
private Socket s;
public ChatRoomServerThread(Socket s){
this.s=s;
}
public void run(){

BufferedReader br=null;
try {
br=new BufferedReader(new InputStreamReader(s.getInputStream()));
String str;
while(true){
//System.out.println(111);
str=br.readLine();
//System.out.println(str);
String st[]=str.split(":");
if(st[0].equals("%EXIT%")){
for(Socket s:sockets){
PrintWriter pw=new PrintWriter(s.getOutputStream());
pw.println(st[1]+"已经离开"+new Date());
pw.flush();
}
break;
}
for(Socket s:sockets){
PrintWriter pw=new PrintWriter(s.getOutputStream());
pw.println(str);
pw.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
sockets.remove(s);
if(br!=null)try {br.close();} catch (IOException e) {}
if(s!=null)try {s.close();} catch (IOException e) {}
}
}
}

解决方案 »

  1.   

    str = br.readLine();应该是阻塞的呀,上下两个程序是一样的吧
      

  2.   

    我就是这里不明白,每次测试的时候都是在没有输入的时候给我报
    Exception in thread "Thread-0" java.lang.NullPointerException
    at exam.ExamServer$examThread.run(ExamServer.java:83)
    说明程序运行了redline以后的代码,str为null,所以有这个异常,把线程给停下来了,很苦恼
      

  3.   

    是啊,因为readLine没有等待下一次输入,所以str=null,所以回报空指针异常啊
      

  4.   

    你在str比较时都加个条件str!=null,这样就可以避免空指针错误了
      

  5.   

    LZ你把C/S的输入输出流全都初始化后再试试看好像是在客户端断开的时候,readline会直接把null传给str,但是如果把客户端的输出流初始化,再从客户端断开,服务器的输入流就会在客户端断开时抛出异常,这是可以用异常来处理了。
      

  6.   

    这个是一个socket多线程的服务器端 楼主看一下对你有没有帮助package cn.xiaozejun.socket.ch06;import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.HashMap;
    import java.util.Vector;public class ServerXianCheng extends Thread{ private Socket client = null;
    private static Vector<Socket> vec = new Vector<Socket>();
    private static HashMap<Socket, String> hm = new HashMap<Socket,String>();
    //构造方法
    public ServerXianCheng(Socket client)
    {
    this.client = client;
    }
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception{
    ServerSocket server = new ServerSocket(8888);
    while(true)
    {
    Socket client = server.accept();
    System.out.println("服务地址:"+client);
    vec.add(client);
    System.out.println("用户个数:"+vec.size());
    new ServerXianCheng(client).start();

    }

    }

    //重写run方法
    public void run()
    {
    try {
    BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
    String line = "";
    while((line = br.readLine())!=null)
    {
    System.out.println("接收到客服端的数据"+line);
    hm.put(client, line);
    for (int i = 0; i < vec.size(); i++) {
    PrintWriter out = new PrintWriter(vec.get(i).getOutputStream());
    out.println(line);
    out.flush();
    }
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }}
      

  7.   

    建议采用非阻塞通信的 ServerSocketChannel, SocketChannel, Selector
    线程使用 Executors 创建 ExecutorService 执行