Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在同一端口轮询服务器-线程和Java_Java_Multithreading_Sockets - Fatal编程技术网

在同一端口轮询服务器-线程和Java

在同一端口轮询服务器-线程和Java,java,multithreading,sockets,Java,Multithreading,Sockets,我目前正忙于为Call of Duty 1的早期版本开发一个IP禁止工具。显然,这些版本中没有实现这样的功能 我已经完成了一个单线程应用程序,但它对于多个服务器的性能不够好,这就是为什么我要尝试实现线程 现在,每台服务器都有自己的线程。我有一个网络课程,它有一个方法;GetStatus-此方法已同步。此方法使用DatagramSocket与服务器通信。因为这个方法是静态的和同步的,所以我不会遇到麻烦,不会收到一大堆已经在使用的地址异常 但是,我有第二个方法,名为SendMessage。此方法应该

我目前正忙于为Call of Duty 1的早期版本开发一个IP禁止工具。显然,这些版本中没有实现这样的功能

我已经完成了一个单线程应用程序,但它对于多个服务器的性能不够好,这就是为什么我要尝试实现线程

现在,每台服务器都有自己的线程。我有一个网络课程,它有一个方法;GetStatus-此方法已同步。此方法使用DatagramSocket与服务器通信。因为这个方法是静态的和同步的,所以我不会遇到麻烦,不会收到一大堆已经在使用的地址异常

但是,我有第二个方法,名为SendMessage。此方法应该向服务器发送消息。当GetStatus中已经有线程运行时,如何确保SendMessage不能被调用,反之亦然?如果我将两者同步,那么如果线程A在端口99999上打开套接字并调用SendMessage,而线程B在同一端口上打开套接字并调用GetStatus,我仍然会遇到麻烦?游戏服务器通常托管在相同的端口上

我想我真正想要的是一种使整个类同步的方法,这样一个线程一次只能调用和运行一个方法

希望我试图完成/避免的事情能在这篇文章中说清楚


非常感谢您提供的任何帮助。

我认为您可能误解了套接字的工作原理,并将套接字的客户端和服务器端弄糊涂了。如果您正在发送消息,通常是通过客户端套接字完成的。它们没有绑定到静态端口号-绑定到特定端口的是您调用accept的服务器套接字

您可以拥有任意数量的客户端,最多可以达到合理的限制-任何一个网络接口最多可连接约60000个客户端


有关客户端和服务器端套接字的介绍,请参阅Sun课程:

我认为您可能误解了套接字的工作原理,并混淆了套接字的客户端和服务器端。如果您正在发送消息,通常是通过客户端套接字完成的。它们没有绑定到静态端口号-绑定到特定端口的是您调用accept的服务器套接字

您可以拥有任意数量的客户端,最多可以达到合理的限制-任何一个网络接口最多可连接约60000个客户端

有关客户端和服务器端套接字的介绍,请参阅Sun课程:

现在,每台服务器都有自己的线程

为什么在同一个应用程序中需要两台服务器?!?如果您将两台服务器拆分为单独的应用程序,那么如果它们都尝试使用相同的端口,您仍然会遇到相同的问题。。。i、 e.您必须为每台服务器指定一个端口。若这真的是一个线程问题,那个么请阅读下面关于如何解决这个问题的想法

两个线程不可能执行同一类的正确同步方法。。。如果你有适当的同步,那么就没有办法体验你所描述的。以下是您的班级应该是什么样子:

class Networking 
{
    public synchronized Status getStatus() {
        Status stat =  new Status();
        // ...
        // Get status logic
        // ...
        return stat;// return the status
    }

    public synchronized void sendMessage(Message msg) {
        // ...
        // Send the message logic
        // ...
    }
}
因此,只要您在同一个网络实例上调用这些方法,即每个线程没有单独的网络类实例,那么您就不会看到任何问题。以下是synchronized关键字为您所做的工作:

首先,不可能在上两次调用同步方法 要交错的同一对象。什么时候 一个线程正在执行一个同步线程 对象的方法,所有其他 调用同步的线程 同一对象块的方法 暂停执行,直到第一个 线程是用对象完成的

其次,当同步方法退出时,它会自动建立 发生在与任何人发生关系之前 后续调用 同步的方法 对象这保证了这些变化 对象的状态是可见的 所有线程

如果希望在Networking类的所有实例中同步方法,则需要使用同步语句:

class Networking 
{
    private static final Object lock = new Object();

    public synchronized Status getStatus() {
        synchronized(lock){
            Status stat =  new Status();
            // ...
            // Get status logic
            // ...
            return stat;// return the status
        }
    }

    public synchronized void sendMessage(Message msg) {
        synchronized(lock){
            // ...
            // Send the message logic
            // ...
        }
    }
}
现在,每台服务器都有自己的线程

为什么在同一个应用程序中需要两台服务器?!?如果您将两台服务器拆分为单独的应用程序,那么如果它们都尝试使用相同的端口,您仍然会遇到相同的问题。。。i、 e.您必须为每台服务器指定一个端口。若这真的是一个线程问题,那个么请阅读下面关于如何解决这个问题的想法

两个线程不可能执行同一类的正确同步方法。。。如果你有适当的同步,那么就没有办法体验你所描述的。以下是您的班级应该是什么样子:

class Networking 
{
    public synchronized Status getStatus() {
        Status stat =  new Status();
        // ...
        // Get status logic
        // ...
        return stat;// return the status
    }

    public synchronized void sendMessage(Message msg) {
        // ...
        // Send the message logic
        // ...
    }
}
所以只要你在同一个网络上调用这些方法 ing实例,即每个线程没有单独的Networking类实例,那么您不应该看到任何问题。以下是synchronized关键字为您所做的工作:

首先,不可能在上两次调用同步方法 要交错的同一对象。什么时候 一个线程正在执行一个同步线程 对象的方法,所有其他 调用同步的线程 同一对象块的方法 暂停执行,直到第一个 线程是用对象完成的

其次,当同步方法退出时,它会自动建立 发生在与任何人发生关系之前 后续调用 同步的方法 对象这保证了这些变化 对象的状态是可见的 所有线程

如果希望在Networking类的所有实例中同步方法,则需要使用同步语句:

class Networking 
{
    private static final Object lock = new Object();

    public synchronized Status getStatus() {
        synchronized(lock){
            Status stat =  new Status();
            // ...
            // Get status logic
            // ...
            return stat;// return the status
        }
    }

    public synchronized void sendMessage(Message msg) {
        synchronized(lock){
            // ...
            // Send the message logic
            // ...
        }
    }
}
如果线程出现错误,[我]还会遇到麻烦吗 正在打开端口99999上的插座,并且 在线程B运行时调用SendMessage 正在打开同一端口上的套接字 调用GetStatus

这里有两个不同的问题。除了99999不是有效端口之外

UDP本质上是用于多路一对多通信的。您可以打开单个套接字并使用该套接字与任意多个服务器通信。您不必担心在同一个套接字上一个线程发送另一个线程接收,或者两个线程试图同时发送,因为从应用程序的角度来看,对套接字的读写操作是原子的。当您在UDP套接字上发送数据时,您调用的是一个系统调用,该调用将N字节的数据从应用程序的内存空间复制到操作系统内核内存空间的缓冲区中,内核将该数据组装成UDP数据包,该数据包放在队列中进行发送—所有这些都以应用程序看起来原子的方式进行。从UDP套接字读取时也会发生相同的情况,但反向读取除外;内核中的接收缓冲区中存在不同的数据包,当应用程序读取套接字时,这些数据包中的数据会自动从内核缓冲区复制到应用程序的缓冲区中,每个读取操作一个数据包

第二个问题是管理特定服务器的传入和传出数据。听起来您希望每台服务器有一个线程来维护该服务器的状态。发送时,您根本不必担心同步问题。所有线程都可以从同一个套接字发送,并且操作系统内核可以有效地处理同步

然而,接收是一个完全不同的问题。我建议使用一个线程,其唯一任务是从套接字读取传入的数据包并对其进行多路复用。每个服务器线程都有一个线程安全队列,读线程将传入的数据包复制到该队列中。然后,每个服务器线程不必担心从自己的传入数据包队列中读取数据包以外的任何事情——它根本不必处理从套接字读取数据包的问题

如果线程出现错误,[我]还会遇到麻烦吗 正在打开端口99999上的插座,并且 在线程B运行时调用SendMessage 正在打开同一端口上的套接字 调用GetStatus

这里有两个不同的问题。除了99999不是有效端口之外

UDP本质上是用于多路一对多通信的。您可以打开单个套接字并使用该套接字与任意多个服务器通信。您不必担心在同一个套接字上一个线程发送另一个线程接收,或者两个线程试图同时发送,因为从应用程序的角度来看,对套接字的读写操作是原子的。当您在UDP套接字上发送数据时,您调用的是一个系统调用,该调用将N字节的数据从应用程序的内存空间复制到操作系统内核内存空间的缓冲区中,内核将该数据组装成UDP数据包,该数据包放在队列中进行发送—所有这些都以应用程序看起来原子的方式进行。从UDP套接字读取时也会发生相同的情况,但反向读取除外;内核中的接收缓冲区中存在不同的数据包,当应用程序读取套接字时,这些数据包中的数据会自动从内核缓冲区复制到应用程序的缓冲区中,每个读取操作一个数据包

第二个问题是管理特定服务器的传入和传出数据。听起来您希望每台服务器有一个线程来维护该服务器的状态。发送时,您根本不必担心同步问题。所有线程都可以从同一个套接字发送,并且操作系统内核可以有效地处理同步

然而,接收是一个完全不同的问题。我建议
结束时有一个线程,其唯一任务是从套接字读取传入的数据包并将其解复用。每个服务器线程都有一个线程安全队列,读线程将传入的数据包复制到该队列中。这样,每个服务器线程就不必担心从自己的传入数据包队列中读取数据包以外的任何事情-它根本不必处理从套接字读取数据包的问题。

顺便说一句,99999不是一个有效端口-端口是16位无符号数字SendMessage和GetStatus同步在什么位置?端口99999只是一个示例,如果是我写的,你能告诉我端口XXXXX不是一个有效的端口吗?端口呢?顺便说一句,99999不是一个有效的端口-端口是16位无符号的数字SendMessage和GetStatus同步在什么位置?端口99999只是一个例子,如果我写了端口XXXXX,你能告诉我端口XXXXX也不是一个有效的端口吗?端口呢?你不在UDP套接字上调用accept,只在TCP套接字上调用。对-我没有看到它是数据报套接字。你不在UDP套接字上调用accept,只在TCP套接字上调用。对-我没有看到它是数据报套接字。