Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java多客户端套接字服务器回显所有客户端_Java_Sockets - Fatal编程技术网

java多客户端套接字服务器回显所有客户端

java多客户端套接字服务器回显所有客户端,java,sockets,Java,Sockets,我正在处理多客户机套接字,它工作得很好,但是我想到了如何通过将输入的字符串流式传输到所有客户机来公开通信 e、 g如果有3个客户机A、B和C,客户机A向服务器发送“foo”,我希望服务器也将“foo”流式传输给客户机B和C 服务器模块: package multiclient; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.P

我正在处理多客户机套接字,它工作得很好,但是我想到了如何通过将输入的字符串流式传输到所有客户机来公开通信

e、 g如果有3个客户机A、B和C,客户机A向服务器发送“foo”,我希望服务器也将“foo”流式传输给客户机B和C

服务器模块:

package multiclient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

public static void main(String args[]) {

    Socket s = null;
    ServerSocket ss2 = null;
    System.out.println("Server Listening......");
    try {
        ss2 = new ServerSocket(4445); // can also use static final PORT_NUM , when defined

    } catch (IOException e) {
        e.printStackTrace();
        System.out.println("Server error");

    }

    while (true) {
        try {
            s = ss2.accept();
            System.out.println("connection Established");
            ServerThread st = new ServerThread(s);
            st.start();

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Connection Error");

        }
    }

  }

            }

class ServerThread extends Thread {

String line = null;
BufferedReader is = null;
PrintWriter os = null;
Socket s = null;

public ServerThread(Socket s) {
    this.s = s;
}

public void run() {
    try {
        is = new BufferedReader(new InputStreamReader(s.getInputStream()));
        os = new PrintWriter(s.getOutputStream());

    } catch (IOException e) {
        System.out.println("IO error in server thread");
    }

    try {
        line = is.readLine();
        while (line.compareTo("QUIT") != 0) {

            os.println(line);
            os.flush();
            System.out.println("Response to Client  :  " + line);
            line = is.readLine();
        }
    } catch (IOException e) {

        line = this.getName(); //reused String line for getting thread name
        System.out.println("IO Error/ Client " + line + " terminated abruptly");
    } catch (NullPointerException e) {
        line = this.getName(); //reused String line for getting thread name
        System.out.println("Client " + line + " Closed");
    } finally {
        try {
            System.out.println("Connection Closing..");
            if (is != null) {
                is.close();
                System.out.println(" Socket Input Stream Closed");
            }

            if (os != null) {
                os.close();
                System.out.println("Socket Out Closed");
            }
            if (s != null) {
                s.close();
                System.out.println("Socket Closed");
            }

        } catch (IOException ie) {
            System.out.println("Socket Close Error");
        }
    }//end finally
}
}

客户端模块:

package multiclient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

public class Client {

public static void main(String args[]) throws IOException{


InetAddress address=InetAddress.getLocalHost();
Socket s1=null;
String line=null;
BufferedReader br=null;
BufferedReader is=null;
PrintWriter os=null;

try {
    s1=new Socket(address, 4445); // You can use static final constant PORT_NUM
    br= new BufferedReader(new InputStreamReader(System.in));
    is=new BufferedReader(new InputStreamReader(s1.getInputStream()));
    os= new PrintWriter(s1.getOutputStream());
}
catch (IOException e){
    e.printStackTrace();
    System.err.print("IO Exception");
}

System.out.println("Client Address : "+address);
System.out.println("Enter Data to echo Server ( Enter QUIT to end):");

String response=null;
try{
    line=br.readLine(); 
    while(line.compareTo("QUIT")!=0){
            os.println(line);
            os.flush();
            response=is.readLine();
            System.out.println("Server Response : "+response);
            line=br.readLine();

        }



}
catch(IOException e){
    e.printStackTrace();
System.out.println("Socket read Error");
}
finally{

    is.close();os.close();br.close();s1.close();
            System.out.println("Connection Closed");

}

        }
          }

服务器可以保留所有客户端套接字的集合(直到关闭一个)。当客户端消息到达时,服务器将其写入所有客户端套接字

但是有一个问题,socket.write()是阻塞的,因此如果我们在循环中执行此操作,则速度较慢的客户端将阻塞其余的客户端。如果没有太多的客户端,您可以生成一个新线程来写入每个套接字

在阻塞IO世界中,要实现真正的全双工协议,服务器必须为每个客户端有两个线程,一个用于读取,一个用于写入


如果你足够勇敢,你也可以尝试NIO…

有很多例子。搜索聊天服务器。如果您不介意使用框架,一个好方法是检查SecureChat示例中的工作代码。这是一个简短而集中的例子

编辑:链接带您到示例代码。

我建议:
1.将创建的线程保留在ArrayList中
2.在服务器中创建名为writeString的方法和锁

  private final Lock mutex = new ReentrantLock(true);
  private ArrayList<ServerThread> list = new ArrayList<ServerThread>();
  public void writeString(ServerThread t,String s)
  {
    mutex.lock();

   for(ServerThread th:list)
       if(th!=null && th!=t) //different from the thread receiving the string
          th.writeString(s);  //send string to other threads

    mutex.unlock();
  }
四,。通过修改构造函数保留对主服务器线程的引用

  //in ServerThread
  private Server parent=null;
  SeverThread(Socket s, Server parent)
  {
      this.parent=parent;
      /*the rest of the code*/
  }

  //in Server
  ServerThread st = new ServerThread(s,this);
  st.start();
  list.add(st);
  • 在ServerThread中读取字符串时,调用Server writeString方法以通知所有客户端

     parent.writeString(this,s); //calls the method we created at 2.
    
  •  parent.writeString(this,s); //calls the method we created at 2.