简体   繁体   English

Java套接字问题:消息只能一次传递

[英]Java Socket Issue: Message Can Only Be Passed For One Time

recently I am attempting an exercise that requires to design a server with TWO clients based on tcp socket. 最近,我正在尝试一项练习,该练习要求基于tcp套接字设计具有两个客户端的服务器。 After connected, the SenderClient should send a message typed by user to Server, and Server should then forward that message to the ReceiverClient. 连接后,SenderClient应该将用户键入的消息发送到Server,然后Server应该将该消息转发到ReceiverClient。 It is like: 它像是:

SenderClient -> Server -> ReceiverClient SenderClient->服务器-> ReceiverClient

Only when user types "quit" in sender, all the programs will be terminated, otherwise they are always listening for messages. 仅当用户在发件人中键入“退出”时,所有程序才会被终止,否则它们始终在侦听消息。

Now I have met the problem that: when I run that three programs in Eclipse Luna, what I found is that the message can be successfully passed from SenderClient -> Server -> ReceiverClient for only one time. 现在,我遇到了一个问题:当我在Eclipse Luna中运行这三个程序时,我发现消息只能从SenderClient-> Server-> ReceiverClient成功传递一次。 And after that, the message will be blocked at the Server. 之后,该消息将在服务器处被阻止。 Can you guys also run those three programs on your computer to see the strange phenomenon. 你们还可以在计算机上运行这三个程序来查看奇怪的现象吗? Thank you and really need help here. 谢谢,在这里真的需要帮助。

import java.io.*;
import java.net.*;

public class Server {

public static void main (String args[]) {

    InputStream is = null;
    InputStreamReader isr = null;
    BufferedReader br = null;
    OutputStream os = null;
    PrintWriter pw = null;

    String info = null;

    try {
        // listening to port
        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("Server is listening to port 8888...");
        while (true) {
            // respond to clients
            Socket receiverSocket = serverSocket.accept();
            System.out.println("receiver client connected!");
            Socket senderSocket = serverSocket.accept();
            System.out.println("sender client connected!");
            // get input stream, read messages from sender
            is = senderSocket.getInputStream();
            isr = new InputStreamReader(is);
            br = new BufferedReader(isr);
            info = br.readLine();
            // close all resources when user types "quit"
            if (info.equalsIgnoreCase("quit")) {
                // close resources when user types "quit"
                is.close();
                isr.close();
                br.close();
                os.close();
                pw.close();
                serverSocket.close();
                System.out.println("Server terminated!");
                break;
            }
            // print out the message
            if (info != null) {
                System.out.println("Sender -> Server: " + info);
            }               
            // get output stream, forward messages to receiver          
            os = receiverSocket.getOutputStream();
            pw = new PrintWriter(os);
            pw.println(info);
            pw.flush();
        } // end while
    } catch (IOException e) {
        e.printStackTrace();
    } // end try...catch

} // end main method

} // end class Server


import java.io.*;
import java.net.*;

public class ReceiverClient {

    public static void main (String args[]) {

        InputStream is = null;
        BufferedReader br = null;

        String info = null;

        try {
            while (true) {
                // create receiver socket with host and port number
                Socket receiverSocket = new Socket("localhost", 8888);
                // get input stream, read the information
                is = receiverSocket.getInputStream();
                br = new BufferedReader(new InputStreamReader(is));
                info = br.readLine();
                // close all resources when user types "quit"
                if (info.equalsIgnoreCase("quit")) {
                    is.close();
                    br.close();
                    System.out.println("Receiver client terminated!");
                    break;
                }
                // print out the message
                if (info != null) {
                    System.out.println("Sender -> Server -> Receiver: " + info);
                }
                receiverSocket.close();
            } // end while
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } // end try...catch

    } // end main method

} // end class ReceiverClient

import java.io.*;
import java.net.*;

public class SenderClient {

    public static void main (String args[]) {

        OutputStream os = null;
        PrintWriter pw = null;
        BufferedReader br = null;

        String userInput = null;

        try {
            while (true) {
                // create sender socket with host and port number
                Socket senderSocket = new Socket("localhost", 8888);
                // get message from user input
                System.out.println("Please input a message:");
                br = new BufferedReader(new InputStreamReader(System.in));
                userInput = br.readLine();
                // get output stream, send message to server
                os = senderSocket.getOutputStream();
                pw = new PrintWriter(os);
                pw.println(userInput);
                pw.flush();
                senderSocket.close();
                // close all resources when user types "quit"
                if (userInput.equalsIgnoreCase("quit")) {
                    os.close();
                    pw.close();
                    System.out.println("Sender client terminated!");
                    break;
                }
            } // end while
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } // end try...catch    

    } // end main method

} // end class SenderClient

Socket receiverSocket = serverSocket.accept();

The accept() method of ServerSocket is a blocking operation: it waits for an incoming connection and until then the thread this code runs on waits. ServerSocketaccept()方法是一项阻止操作:它等待传入的连接,直到此代码运行的线程等待。 The first time the loop is executed correctly because you have the two clients connect to the server. 第一次正确执行循环,因为您有两个客户端连接到服务器。 The second time the loop gets executed you wait for another incoming client. 第二次执行循环时,您等待另一个传入的客户端。 A solution for this is to handling of the messages in a separate thread by implementing the java.lang.Runnable interface, which is the code that runs on the newly launched thread: 一种解决方案是通过实现java.lang.Runnable接口在单独的线程中处理消息,该接口是在新启动的线程上运行的代码:

class ClientConnection implements Runnable{

private Socket sender;
private Socket receiver;

public ClientConnection(Socket sender, Socket receiver){
    this.sender = sender;
    this.receiver = receiver;
}

@Override
public void run(){
    is = sender.getInputStream();
    isr = new InputStreamReader(is);
    br = new BufferedReader(isr);
    OutputStream os = receiver.getOutputStream();
    PrintWriter pw = new PrintWriter(os);

    boolean clientQuit = false;

    while(!clientQuit){
        info = br.readLine();   

        if (info.equalsIgnoreCase("quit")) {
            // close resources when user types "quit"
            is.close();
            isr.close();
            br.close();
            os.close();
            pw.close();
            serverSocket.close();
            System.out.println("Server terminated!");
            clientQuit = true;
        } else{
            pw.println(info);
            pw.flush;
        }
    }
}

} }

Whenever the server gets two incoming connections, it fires up a new Thread that will handle the connection and then continues on accepting new incoming connections: 每当服务器获得两个传入连接时,它都会启动一个新的Thread来处理该连接,然后继续接受新的传入连接:

while (true) {
    // respond to clients
    Socket receiverSocket = serverSocket.accept();
    System.out.println("receiver client connected!");
    Socket senderSocket = serverSocket.accept();
    System.out.println("sender client connected!");

    ClientConnection connection = new ClientConnection(senderSocket, receiverSocket);
    Thread connectionThread = new Thread(connection);
    connectionThread.start();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM