【问题标题】:TCP threaded server/clientTCP线程服务器/客户端
【发布时间】:2014-03-04 01:03:27
【问题描述】:

我正在尝试制作一个接受多个客户端的线程 TCP 服务器。它只接受一个客户。关于如何使服务器接受多个客户端的任何想法?

这是我目前尝试过的:

我更改了服务器代码。我同时运行了服务器和客户端,但似乎只有一个线程在工作。我应该更改端口还是什么?

服务器代码:

package tcpecho;

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


class TCPserver  implements Runnable {
private static String clientMSG;
private static String serverRespond;
private static ServerSocket MySocket=null;
private static Socket client;
private static Socket connectionSocket = null;
private BufferedReader inFromClient = null;
public TCPserver(Socket client){
    TCPserver.client=client;}

public static void main(String[] args)  {

    try {
        MySocket  = new ServerSocket(6880);
        System.out.println("TCP server is listining");
    } catch (IOException e) {

    System.err.println("TCP server is not listining :   "+MySocket.getLocalPort());
    } 

    try {
        connectionSocket = MySocket.accept();
        (new Thread(new TCPserver(connectionSocket))).start();

        System.out.println("Is connected now : "+connectionSocket.getInetAddress());

    } catch (IOException e) {

        System.err.print("Accept failed");
    }
}



public void socketProcess( )
{

    try {
        inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
    } catch (IOException e) {
        System.err.println("Message from client is not reachable");
    }

    DataOutputStream outToClient = null;
    try {
        outToClient = new DataOutputStream(connectionSocket.getOutputStream());
    } catch (IOException e) {
        System.err.println("Message to client is not reachable");

    }

    try {
        clientMSG = inFromClient.readLine();
    } catch (IOException e) {
        System.err.println("Message from client is not readable");
    }

    serverRespond = clientMSG +connectionSocket.getInetAddress()+ '\n';

    try {
        outToClient.writeBytes(serverRespond);
    } catch (IOException e) {
        System.err.println("Message to client is not out");
    } 

    try {
        MySocket.close();
    } catch (IOException e1) {

        System.err.println("Unable to close the socket");
    }

}



@Override
public void run() {
    socketProcess();

} 

}

这是我的客户端代码:

package task3;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.Socket;

class Client {
    public static void main(String argv[]) throws Exception {

        String str;
        String strFromServer;
        BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));

        Socket client = null;
        // for(int i=0;i<10;i++){
        int port = 6880;
        try {
            client = new Socket("192.168.56.1", port);
        } catch (Exception e) {
            System.err.println("Couldn't connect to the port" + port);
            System.exit(1);
        }

        DataOutputStream outToServer = new DataOutputStream(client.getOutputStream());

        BufferedReader inFromServer = new BufferedReader(new InputStreamReader(client.getInputStream()));
        System.out.println("Write a message to the server :");
        str = inFromUser.readLine();

        outToServer.writeBytes(str + '\n');
        strFromServer = inFromServer.readLine();
        System.out.println("Respond from server: " + strFromServer);
        client.close();
    }
}

【问题讨论】:

  • 收到答案后不要破坏您的问题。

标签: java multithreading sockets networking tcp


【解决方案1】:

在你这样做之后

connectionSocket = MySocket.accept();

您需要将此connectionSocket 实例传递给新线程并在该线程上调用start

另外,将所有 connectionSocket 处理逻辑移动到 Thread 类的 run 方法
(这个逻辑目前在上面提到的这行之后的main方法中)。

要实现您自己的Thread,您可以扩展Thread 或实现Runnable

查看此链接了解更多详情:Java Threads

【讨论】:

  • 另外,您不应该在循环中创建新的 ServerSocket。创建一次就足够了。
  • 正确,我猜他应该删除整个循环。我猜他是在尝试支持接受多个客户端时添加的。
  • 我把connectionSocket传给了一个新线程,但是我不能在run方法中移动所有的进程,会抛出很多错误。
  • connectionSocket = MySocket.accept(); (new Thread(new TCPserver(connectionSocket))).start();
  • 你需要重新设计/重新设计,我不是说你应该只是复制粘贴。
【解决方案2】:

只是一个建议,如果您要始终向所有客户端打开多个线程,您可能需要查看使用非阻塞 io 的 java.nio 包。

这将允许您处理更多的连接。

【讨论】:

  • 线程池从程序员的控制中抽象出来。您通常使用 nio.channel 子类和选择器。它类似于 C/C++ 中的 select() 函数。根据您使用 TCP 服务器的方式,研究 java.nio 可能更有利。
猜你喜欢
  • 2019-04-18
  • 2016-09-26
  • 2015-08-29
  • 2019-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-20
相关资源
最近更新 更多