繁体   English   中英

客户端程序可以具有服务器套接字以与其他客户端程序进行通信吗?

Can a client program have a server socket to communicate to other client programs?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我正在尝试实现一个多线程套接字程序,该程序可模拟五台计算机和一个通过套接字相互通信的控制器。 控制器具有一个服务器套接字,该套接字可以接受来自计算机的传入套接字。 一旦达到系统的最大容量(比方说五个),它将使用接受传入套接字时创建的线程向这些计算机发送启动消息。

当每台计算机从控制器接收到“开始”消息时,我希望每台计算机都能够与其他计算机通信(无需依赖控制器(从计算机到控制器到另一台计算机的中继消息)。我认为可行的是让每台计算机实例化一个服务器套接字,以便它可以接受来自计算机的传入套接字;还可以实例化另一个客户端套接字,以便来自其他计算机的其他服务器套接字可以接受它。

我知道这听起来很混乱,但是基本上我想在每个客户端程序(计算机)上使用服务器套接字,以便它可以在不依赖控制器的情况下侦听其他客户端(计算机)。

这可能吗? 我可以实例化服务器程序套接字的每个客户端程序(计算机),以便它可以侦听其他计算机吗? 它是否需要与控制器的服务器插槽不同的IP地址和/或端口号? 我是否需要为x数量的计算机实例化x数量的套接字?

也许我的Java代码可以解决这个问题。

Controller.java

    package timetableexchange;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class Controller {

final int MAX_SYSTEMS = 2;

static ArrayList<ServerConnection> conns = new ArrayList<ServerConnection>();   // connections to computer
static int finishedCount = 0;                                                   // number of finished computers

ServerSocket ss;            // server socket

public static void main(String[] args) throws IOException {
    // Instantiate controller
    new Controller(8000);
}

public Controller(int port) throws IOException {
    // Instantiate server socket
    ss = new ServerSocket(8000);
    int i = 0;
    // Listen and accept clients (1 for testing)
    while (i < MAX_SYSTEMS) {
        Socket s = ss.accept();
        // add to list
        ServerConnection conn = new ServerConnection(i++, s);
        conns.add(conn);
    }
    // start server connection thread
    for (i = 0; i < conns.size(); ++i) {
        conns.get(i).start();
    }
    ss.close();
}

// Thread for communicating between controller and computer
private class ServerConnection extends Thread {

    Socket socket;
    BufferedReader in;
    PrintWriter out;
    int identifier;

    // constructor
    public ServerConnection(int i, Socket s) throws IOException {
        this.identifier = i;
        this.socket = s;
        this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        this.out = new PrintWriter(socket.getOutputStream(), true);
        System.out.println("Client Connected");
    }

    @Override
    public void run() {
        System.out.println("ServerConnection started");
        // send ID to computers
        sendAll(identifier + "");
        // send Start message to computers
        sendAll("Start");
        // Check if a computer sent back a Finish message
        // If all computers are finished, then send out Tear Down message.
        while (true) {
            try {
                String clientInput = in.readLine();
                if (clientInput.equals("Finish")) {
                    finishedCount += 1;
                    if (finishedCount == conns.size()) {
                        sendAll("Tear Down");
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                break;
            }
        }
    }

    private void sendAll(String text) {
        for (int i = 0; i < conns.size(); ++i) {
            ServerConnection conn = conns.get(i);
            conn.out.println(text);
        }
    }
}

}

Computer.java

package timetableexchange;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Vector;

public class Computer {

final int MAX_SYSTEMS = 2;

int identifier;                                         // Computer ID
int eventCount;                                         // Number of Generated Events
ArrayList<Socket> sockets = new ArrayList<Socket>();    // List of (client) sockets
Vector<Integer> timestamp = new Vector<Integer>();      // Time-stamp vector

Socket socketToServer;                                  // Socket to Connect to Controller
BufferedReader inputFromServer;                         // Input Stream from Controller
PrintWriter outputToServer;                             // Output Stream to Controller
String textFromServer;                                  // String sent from Controller

ServerSocket ss;                                        // Server Socket to communicate with other clients (computers)
Socket socketToClient;                                  // Socket to Connect to Computer
BufferedReader inputFromClient;                         // Input Stream from Computer
PrintWriter outputToClient;                             // Output Stream to Computer

public static void main(String[] args) throws IOException {
    // Instantiate Computer
    new Computer("127.0.0.1", 8000);
}

// Constructor
public Computer(String hostname, int port) throws IOException {
    // Instantiate Socket (to Controller) and Streams (to Controller)
    socketToServer = new Socket(hostname, port);
    inputFromServer = new BufferedReader(new InputStreamReader(socketToServer.getInputStream()));
    outputToServer = new PrintWriter(socketToServer.getOutputStream(), true);

    // Check if Controller sent the computer its ID
    while (true) {
        try {
            textFromServer = inputFromServer.readLine();
            // set identifier
            identifier = Integer.parseInt(textFromServer);
            System.out.println(identifier);
            break;  // break loop
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
    }

    // Check if Controller sent the start message
    while (true) {
        textFromServer = inputFromServer.readLine();
        if (textFromServer.equals("Start"))
            System.out.println("Start message received");
            break;  // break loop
    }

    // Instantiate Server Socket (for Clients)
    ss = new ServerSocket(port + identifier + 1);

    // Instantiate Client Socket for Other Clients to Hear
    socketToClient = new Socket();
    inputFromClient = new BufferedReader(new InputStreamReader(socketToClient.getInputStream()));
    outputToClient = new PrintWriter(socketToClient.getOutputStream());

    // listen to server socket and add accepted socket to list  
    for (int i = 0; i < MAX_SYSTEMS - 1; ++i) {
        Socket s = ss.accept();
        System.out.println("Client accepted");
        sockets.add(s);
    }

    Thread readEvent = new Thread(new Runnable() {
        @Override
        public void run() {
            /**
             * Read from input stream
             * Read the vector inside the input stream
             * Compare vectors and choose the largest integer (synchronized)
             * Add 1 to the corresponding socket. (synchronized)
             */
        }
    });

    Thread writeEvent = new Thread(new Runnable() {
        @Override
        public void run() {
            /**
             * Generate random number between 0 and 4.
             * If zero, then add 1 to its own socket in vector.
             * Else, send vector to random socket via output stream
             */
        }
    });

    readEvent.start();
    writeEvent.start();
}

}

感谢您的帮助!

1 个回复

简而言之:

这可能吗?

是的,为什么不?

我可以实例化服务器程序套接字的每个客户端程序(计算机),以便它可以侦听其他计算机吗?

是的-您可以做任何您想要或需要的事情

它是否需要与控制器的服务器插槽不同的IP地址和/或端口号?

IP地址属于“物理计算机” /网络接口,与您尝试执行的操作无关紧要-所有地址都可以在一台计算机上运行,​​并且都可以在同一IP地址上运行(例如127.0.0.1)。 您必须为要打开的每个服务器套接字都具有专用端口,并且客户端套接字必须知道要与之通信的IP和端口号。 对于客户端套接字,您无需关心IP或端口号。

我是否需要为x数量的计算机实例化x数量的套接字?

问题对我来说意义不大-这是您的设计决策,您需要实例化多少个服务器套接字-一个端口一个服务器套接字,就是这样。

2 Python基本客户端服务器套接字程序

我从realpython( https://realpython.com/python-sockets/#echo-client-and-server )尝试了用于客户端和服务器的基本程序 虽然这些命令在同一台计算机上运行时可以正常工作,但在不同计算机上尝试时存在以下问题: Conn ...

3 Linux套接字客户端/服务器程序

您好我的服务器程序是: 所以我有一个简单的服务器程序,也有一个客户端程序。 我的问题是,当我在不同终端上的同一台机器上同时运行这两个客户端时,客户端输出正常。 服务器虽然不打印等待线,但它堆叠起来使我无法使用终端。 有什么问题 ? ...

4 为什么我的套接字只能通信客户端到服务器而不是服务器到客户端?

我编写了一个带有守护程序线程的简单Java调度程序,以处理传入的流量,并使用另一个线程发送命令。 当服务器收到第一条消息时,问题就来了,然后客户端/服务器系统卡在服务器试图向客户端发送响应的位置。 当服务器发送数据时,两端的套接字只是简单地冻结。 我已经将原来的问题简化为回显服务器 ...

7 C中涉及套接字和客户端-服务器通信的程序出现问题

我正在使用C语言开发一个程序,该程序涉及客户端与服务器之间的连接以及两方之间的通信。 该程序包括客户端向服务器发送一封信,然后服务器获取该信件。 然后,服务器在当前文件目录(在Linux中)中搜索以该字母开头的文件,并向客户端发送该文件的字节数和该文件的文本。 整个程序很长,对于作 ...

8 服务器应用程序和使用Java的Matlab客户端之间的套接字通信

我有一个书面的C ++服务器应用程序,我希望能够从Matlab控制。 到目前为止,我已经使用mex函数进行套接字通信,但我想抛弃mex函数并直接在m文件中使用内联Java。 这将是一个更简化的解决方案。 我的基于C ++的独立应用程序需要按以下顺序显示包含以下数据的消息。 。 。 ...

10 客户端-服务器套接字通信

问题 如果只能在客户端上使用,如何在服务器和客户端之间发送UTF-8数据 ? 文件 从此流中读取单个字节,并将其作为介于0到255之间的整数返回。如果已到达流的末尾,则返回-1。 没有reader.readLine()和其他任何内容。 (与读者我看不到流的 ...

暂无
暂无

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

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