Java中使用TCP的多线程服务器

时间:2011-07-22 00:00:46

标签: multithreading tcp client-server localhost

我正在尝试在Client / Server之间实现简单的TCP连接。我使服务器多线程,以便它可以从单个客户端获取多个请求(例如查找用户提供的一串数字的总和,最大值,最小值)或接受来自不同客户端的多个连接。我在我的机器上运行它们,但服务器似乎没有推出答案。不知道我在这里做错了什么 -

public final class CalClient {

static final int PORT_NUMBER = 6789;  

public static void main (String arg[]) throws Exception
{
    String serverName;
    @SuppressWarnings("unused")
    String strListOfNumbers = null;
    int menuIndex;
    boolean exit = false;

    BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));

    System.out.println("Please enter host name...");
    System.out.print("> ");
    serverName = inFromUser.readLine();

    Socket clientSocket = new Socket(serverName, PORT_NUMBER);
    DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
    BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

    //outToServer.writeBytes(serverName + '\n');

    System.out.println("");
    System.out.println("Enter 1 to enter the list of numbers");
    System.out.println("Enter 2 to perform Summation");
    System.out.println("Enter 3 to calculate Maximum");
    System.out.println("Enter 4 to calculate Minimum");
    System.out.println("Enter 5 to Exit");

    while (!exit) {
        System.out.print(">");
        menuIndex = Integer.parseInt(inFromUser.readLine());

        if (menuIndex == 1) {   
            System.out.println("Please enter the numbers separated by commas.");
            System.out.print(">");
            strListOfNumbers = inFromUser.readLine();
            outToServer.writeBytes("List" + strListOfNumbers);
            //continue;
        }
        else if (menuIndex == 2) {
            outToServer.writeBytes("SUM");
            System.out.println(inFromServer.readLine());
        }
        else if (menuIndex == 3) {
            outToServer.writeBytes("MAX");
            System.out.println(inFromServer.readLine());
        }
        else if (menuIndex == 4) {
            outToServer.writeBytes("MIN");
            System.out.println(inFromServer.readLine());
        }
        else if (menuIndex == 5) {
            outToServer.writeBytes("EXIT");
            exit = true;
        }
    }
}

}

public final class CalServer 
{

      static final int PORT_NUMBER = 6789;  

public static void main(String[] args) throws IOException 
{
    try {
        ServerSocket welcomeSocket = new ServerSocket(PORT_NUMBER);
        System.out.println("Listening");
        while (true) {
            Socket connectionSocket = welcomeSocket.accept();

            if (connectionSocket != null) {
                CalRequest request = new CalRequest(connectionSocket);
                Thread thread = new Thread(request);
                thread.start();
            }
        }
    } catch (IOException ioe) {
        System.out.println("IOException on socket listen: " + ioe);
        ioe.printStackTrace();
    }
}
}

final class CalRequest implements Runnable
{
Socket socket;
BufferedReader inFromClient;
DataOutputStream outToClient;

TreeSet<Integer> numbers = new TreeSet<Integer>();
int sum = 0;

public CalRequest(Socket socket)
{
    this.socket = socket;
}

@Override
public void run() 
{
    try {
        inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
        outToClient = new DataOutputStream(socket.getOutputStream());

        while(inFromClient.readLine()!= null) {
            processRequest(inFromClient.readLine());
        }       

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

public void processRequest(String string) throws IOException
{
    String strAction = string.substring(0,3);

    if (strAction.equals("LIS")) {
        String strNumbers = string.substring(5);
        String[] strNumberArr;
        strNumberArr = strNumbers.split(",");

        // convert each element of the string array to type Integer and add it to a treeSet container. 
        for (int i=0; i<strNumberArr.length; i++)
            numbers.add(new Integer(Integer.parseInt(strNumberArr[i])));
    }
    else if (strAction.equals("SUM")) {
        @SuppressWarnings("rawtypes")
        Iterator it = numbers.iterator();
        int total = 0;

        while (it.hasNext()) {
            total += (Integer)(it.next());
        }
    }
    else if (strAction.equals("MAX")) {
        outToClient.writeBytes("The max is: " + Integer.toString(numbers.last()));
    }
    else if (strAction.equals("MIN")) {
        outToClient.writeBytes("The max is: " + Integer.toString(numbers.first()));
    }
}

}

2 个答案:

答案 0 :(得分:1)

由于您使用readLine(),我猜您确实需要发送行终止符。

答案 1 :(得分:1)

我对TCP套接字通信的经验仅使用ASCII数据,而我的代码反映了我的信念。如果是这种情况,您可以尝试这样做:

首先,尝试像这样实例化数据流:

socket     = new Socket (Dest, Port);
toServer   = new PrintWriter (socket.getOutputStream(), true);
fromServer = new BufferedReader (new InputStreamReader
    (socket.getInputStream()), 8000);

最后,printWriter构造函数告诉它在发出println时自动刷新(可爱术语)缓冲区。

实际使用套接字时,请使用以下命令:

toServer.println (msg.trim());
resp = fromServer.readLine().trim();

我不必自己将\ n附加到传出文本中,但这可能与我的具体情况有关(更多内容见下文)。传入的数据需要在其末尾有一个\ n或者readLine不起作用。我假设有一些方法可以逐字节地读取套接字,但代码也不会那么简单。

不幸的是,我正在与之通信的TCP服务器是一个C ++程序,因此我们确保输入数据中存在\ n的方式不适合您(并且可能不需要传出的数据)。

最后,如果它有帮助,我基于这个网络示例构建了我的代码:

http://content.gpwiki.org/index.php/Java:Tutorials:Simple_TCP_Networking

编辑:我发现了另一个使用DataOutputStream的代码示例...假设您还没有看到它,您可能会发现它很有用。

http://systembash.com/content/a-simple-java-tcp-server-and-tcp-client/