多线程服务器/客户端聊天

时间:2014-12-18 16:10:27

标签: java multithreading sockets client server

所以这是我在这里的第一篇文章,我目前正在尝试使用套接字编程创建一个Java客户端/服务器聊天应用程序。

我目前让服务器等待客户端连接,然后将客户端的消息传递回客户端。到目前为止,我尝试了不同的方法,使服务器不断收听新客户端并连接它们,允许它们相互发布和查看消息。

你能指出我正确的方向以及我应该如何实现这个目标吗?


SERVER

  

class TCPServer {
private ServerSocket serverSocket;
private int port;
String newLine = System.getProperty("line.separator");
public TCPServer(int port) {
    this.port = port;
}
public void begin() throws IOException {

    System.out.println("Starting the server at port: " + port);
    serverSocket = new ServerSocket(port);

    System.out.println("Waiting for clients... " + newLine);

    try {

        Socket connectionSocket = serverSocket.accept();

        DataOutputStream hello =
                new DataOutputStream(connectionSocket.getOutputStream());
        hello.writeUTF("You have successfully connected!" + newLine + "please type your      username");


        //A client has connected to this server. Get client's username
        String username = getUserName(connectionSocket);
        System.out.println(username + " has connected" + newLine);
        //Start chat method
        startChat(connectionSocket, username);
    } catch (Exception e) {
    }

}

public String getUserName(Socket connectionSocket) throws IOException {
    String clientUserName;
    // ArrayList clients = new ArrayList();


    BufferedReader userNameClient =
            new BufferedReader(new InputStreamReader(
            connectionSocket.getInputStream()));


    clientUserName = userNameClient.readLine();
    //clients.add(clientUserName);


    DataOutputStream greetingFromServer =
            new DataOutputStream(connectionSocket.getOutputStream());
    //writeUTF Caused incorrect key codes to appear at beginning of String
    greetingFromServer.writeBytes("Welcome " + clientUserName + ", please type your message" + newLine);


    return clientUserName;
}

public void startChat(Socket connectionSocket, String username) throws IOException {
    String clientSentence;
    String clientMessageOut;



    while (true) {
        //Socket connectionSocket = welcomeSocket.accept();

        BufferedReader inFromClient =
                new BufferedReader(new InputStreamReader(
                connectionSocket.getInputStream()));
        DataOutputStream outToClient =
                new DataOutputStream(connectionSocket.getOutputStream());



        //Loops to check if client message is not empty
        while ((clientSentence = inFromClient.readLine()) != null) {
            outToClient.writeBytes(username + ": " + clientSentence + newLine);
            if (clientSentence.equals("close")) {
                System.out.println(username + " has left the server");
            }

        }
    }
}

public static void main(String[] args) throws Exception {
    int port = 6788;

    TCPServer welcomeSocket = new TCPServer(port);
    welcomeSocket.begin();


}

}


客户端

  

class TCPClient {

public static void main(String[] args) throws Exception {
    String sentence;
    String modifiedSentence;
    boolean keepConnection = true;
    int port = 6788;
    Scanner inFromUser = new Scanner(System.in);

    Socket clientSocket = new Socket("localhost", 6788);
    //System.out.println("You are connented to server"+ '\n'+"Please enter your username: ");
    String newLine = System.getProperty("line.separator");

    //Recieve greeting message
    InputStream messageFromServer = clientSocket.getInputStream();
    DataInputStream in =
            new DataInputStream(messageFromServer);
    System.out.println("FROM SERVER: " + in.readUTF());


    DataOutputStream outToServer =
            new DataOutputStream(clientSocket.getOutputStream());
    BufferedReader inFromServer =
            new BufferedReader(new InputStreamReader(
            clientSocket.getInputStream()));

    while ((sentence = inFromUser.nextLine()) != null) {
        outToServer.writeBytes(sentence + '\n');
        modifiedSentence = inFromServer.readLine();
        System.out.println("sentence = " + sentence);
        System.out.println(modifiedSentence);
        if (sentence.equals("close")) {
            System.out.println("You have left the server");
            outToServer.writeBytes("close" + newLine);
            break;
        }
    }
    clientSocket.close();
}

}

3 个答案:

答案 0 :(得分:0)

您可以使用while(true){}while((socket = serverSocket.accept()) != null)让服务器无限循环。

答案 1 :(得分:0)

要使服务器能够连接到多个客户端,您可以创建一个接受新连接的循环:

while (true) {
    try {
        Socket connectionSocket = serverSocket.accept();
        ...
    } 
    ...
}

为了保持响应,您可以在新线程中使用每个客户端或维护线程池,并为每个新连接向其提交任务。

答案 2 :(得分:0)

以下是您如何做到这一点的示例(taken from ServerSocketEx)。 ServerSocketEx扩展了ServerSocket,但这只是为了易于使用; super.accept之后的所有代码都与您的问题相关。

正如其他人所建议的那样,你应该在一个循环中调用accept(),包含try {} catch(IOException ...);如果您选择关闭ServerSocket

,则可以关闭
public Socket accept() throws IOException {
    Socket s = super.accept();
    if (getSocketRunnerFactory() != null) {
        SocketRunner runner = getSocketRunnerFactory().createSocketRunner(s);
        if (executor != null) {
            Future f = 
                executor.submit(runner);
            if (futures != null) futures.add(f);
        }
        else {
            Thread t = new Thread(runner);
            t.start();
        }
    }
    return s;
}