Java套接字 - 并行多次运行同一客户端。

时间:2015-10-22 05:39:42

标签: java multithreading sockets parallel-processing client-server

(免责声明此部分代码与在线教程类似)

我想我已经做到这一点,以便我的服务器可以使用线程一次处理多个请求,但我不完全确定。最重要的是,我不知道我将如何实时发送多个请求。

我的目标是多次并行运行我的客户端代码,看看如果多个客户端同时连接到服务器会发生什么。

客户端代码(在单独的项目包中):

        Client clientSocket = new Client(9990,"localhost");
        Socket socket = new Socket(clientSocket.host,clientSocket.portNumber);
        clientSocket.performTask(socket);

(“performTask(socket)”将数据发送到服务器以执行任务)

服务器代码(与客户端代码分开的项目包):

    Server server = new Server(9990);
    int clientNumber = 0;
    ServerSocket socket = new ServerSocket(server.portNumber);
    try { 
        while (true) {
            new ServerHandler(socket.accept(),clientNumber).go();
            clientNumber++;
        }
    }
    finally {
        socket.close();
        }
}

ServerHandler类(与服务器代码相同的项目包):

public class ServerHandler extends Thread {
    private static Socket socket;
    private static int clientNumber;

    public ServerHandler(Socket socket, int clientNumber) {
        ServerHandler.socket = socket;
        ServerHandler.clientNumber = clientNumber;
    }

    public void go() {
        while(true) {
        try {
            //do calculation, do server tasks, etc.
            }

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

因此,当客户端连接到服务器时,服务器会实现ServerHandler类来进行必要的计算:这样做的想法是多个客户端可以同时连接所有客户端。

所以我的问题分为两部分:

(1)我是否已将程序设置为允许多线程,或者我是否在某个地方犯了错误? (例如有人告诉我,我需要在某个地方使用“Runnable”来使用多线程,我注意到我没有)

(2)修复我的代码以允许多线程后,我如何实际使用它来让我并行运行我的客户端代码?

2 个答案:

答案 0 :(得分:1)

对于初学者来说,ServerHandler扩展了Thread课程。因此,要使其作为单独的线程运行,请始终通过调用start()方法来调用。您正在调用自定义go方法,这将使ServerHandler在与无限循环相同的线程中执行。所以它应该是这样的ServerHandler(socket.accept(),clientNumber).start()。此外,最好实现Runnable,因为java不支持通过" extends"进行多重继承。概念。因此,将来如果您的ServerHandler需要实际扩展自定义类,它将无法扩展Thread类。它更好地实现接口,因为对于您可以实现的数量没有限制。

因此,实现Runnable接口是一个很好的设计选择。您可以通过将客户端变为线程模型来并行运行客户端代码。以下是多个客户端套接字并行连接到服务器的示例

服务器代码

public class WebServer {
    static int hitCount = 0;

    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = new ServerSocket(7777, 10000);
        while (true) {
            Socket defaultSocket = serverSocket.accept();
            new Thread(new ServerSlave(defaultSocket)).start();
            System.out.println("Size is :" + hitCount);
        }

    }
}

class ServerSlave implements Runnable {
    Socket clientSocket;

    public ServerSlave(Socket socket) {
        clientSocket = socket;
        WebServer.hitCount++;
    }

    public void run() {

        try {

            DataInputStream inputStream = new DataInputStream(clientSocket.getInputStream());
            DataOutputStream outputStream = new DataOutputStream(clientSocket.getOutputStream());
            System.out.println(inputStream.readUTF());
            outputStream.writeUTF("Thank you for contacting the web server");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客户代码:

public class Client {
    static int excepCount=0;
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 100; i++) {
            new Thread(new Worker("" + i)).start();
        }
        Thread.sleep(10000);
        System.out.println( Client.excepCount);
    }
}


class Worker implements Runnable {
    String clientName;

    public Worker(String name) {
        clientName = name;
    }

    public void run() {
        System.out.println("Process started for : " + clientName);
        Socket socket = null;
        try {
            socket = new Socket("127.0.0.1", 7777);
            DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
            outputStream.writeUTF("Hello socket. Client number " + clientName + "here");
            InputStream inFromServer = socket.getInputStream();
            DataInputStream in =
                    new DataInputStream(inFromServer);
            System.out.println("Server says " + in.readUTF());
            System.out.println("Closing socket");

        } catch (IOException e) {
            Client.excepCount++;
            e.printStackTrace();
        }finally{
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

答案 1 :(得分:0)

您应该使用多线程。  您必须将方法重命名为“run”/并使用“start”调用该方法。请将服务器端代码更改为

try { 
        while (true) {
            new ServerHandler(socket.accept(),clientNumber).start();
            clientNumber++;
        }
    }
    finally {
        socket.close();
        }

和客户端

public class ServerHandler extends Thread {
    private static Socket socket;
    private static int clientNumber;

    public ServerHandler(Socket socket, int clientNumber) {
        ServerHandler.socket = socket;
        ServerHandler.clientNumber = clientNumber;
    }

    public void run() {
        while(true) {
        try {
            //do calculation, do server tasks, etc.
            }

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