![]() |
1
17
首先,不要将接受的客户机(服务器端)称为其套接字
那是不可能的。你总是要做一个服务器端,它可以接受客户端。现在的问题是:连接的哪一边应该是服务器端?
为什么不立即连接到VNCServer? 但如果你真的想要,你可以这样做: / VNCServer (Server Running) <---. | | LAN -| Connects to VNCServer | | \ MyApp (Server Running --> Accepts from Middle Server) <------. | (Through a router) | Middle server (Server Running --> Accepts client) ---> Connects to Your App ^ | (Through a router) | Client --> Connects to Middle Server --° 这就是没有第三台服务器的情况(我向您推荐): / VNCServer (Server Running) <---. | | LAN -| Connects to VNCServer | | \ MyApp (Server Running --> Accepts Clients) <------. | (Through a router) | Client --> Connects to MyApp --------------------------° 编辑: 我想我现在明白了: 我们必须把你的处境想象成这样: Your Main Server (What you called middle server) (1) | | (2) /â»â»â»â»â»â»â»â»â»â»â»â»â»â»â»â»â»â»/ \â»â»â»â»â»â»â»â»â»â»â»â»â»â»â»â»â»\ | | Your VNCServer <----------------------------> The client (5) (3)
现在桌面共享可以开始了。
我认为这是你能遇到的最好的情况。
|
![]() |
2
5
你为什么要这么做? 如果您想拥有一个“点对点”类型的系统,那么您只需让每个客户机同时运行一个客户机和一个服务器套接字—服务器套接字用于接受来自其他客户机的连接,而客户机套接字用于建立与其他客户机的连接。 在您的示例中,您的应用程序将创建两个客户端套接字,一个连接到VNCServer,另一个连接到“中间服务器”。“中间服务器”将有两个服务器套接字(一个供应用程序连接,一个供用户连接)。在内部,它需要知道如何匹配这些套接字,并在两者之间传递数据。 |
![]() |
3
2
ServerSocket允许您侦听特定端口上的连接。当服务器套接字接受连接时,它会生成另一个线程,并将连接移动到另一个端口,这样原始端口仍然可以侦听其他连接。 客户端在已知端口上启动连接。然后,客户机通常会发送一些请求,而服务器会做出响应。这将重复进行,直到通信完成。这是web使用的简单客户机/服务器方法。 如果您不需要这种机制,并且请求可能随时来自任何一个套接字,那么以您认为合适的方式实现读写器线程。 在内部,它们仍然使用等待机制,因此当它们等待数据到达时,您不应该看到太多的CPU使用情况。 我认为您仍然需要一端作为服务器套接字,因为我认为不可能让客户端套接字接受连接。ClientSocket意味着TCP,它需要一个连接。如果您使用DatagramSocket,这意味着UDP,那么您可以进行客户端到客户端的通信,而不需要连接。 |
|
4
2
在这里
我一次又一次地重新运行,我不断地得到这个,除非,我等了一定的时间,然后再次运行,它和第一次一样正常。 |
![]() |
5
1
你想创建一个模拟的套接字吗?如果是这样的话,嘲弄管道的两边可能比必要的要复杂一些。 另一方面,如果您只想在两个线程之间创建一个数据管道,那么可以使用PipedInputStream和PipedOutputStream。 然而,如果没有更多关于你想要达到的目标的信息,我无法告诉你这些选择中的任何一个是合适的,还是其他的更好。 |
![]() |
6
1
A
现在试着想象一下,如果一个线程在没有人读取的情况下向流中写入大量数据会发生什么。。。缓冲区确实存在,但它们并不是无限的,它们的大小可以不同。最后,您的写入线程将达到缓冲区的限制,并将阻塞,直到有人释放缓冲区。 话虽如此,您现在应该知道,每个流至少需要两个不同的线程:一个用于写入,另一个用于读取写入的字节。 如果您的协议是请求-响应样式,那么每个套接字可以使用2个线程,但不能少于2个。 您可以尝试替换应用程序的网络部分。只需创建一个抽象接口,在其中可以隐藏整个网络部分,如:
通过这种方式,您可以轻松地删除整个网络(包括对象的解码等)并最小化线程。 如果需要二进制数据,可以使用管道,或者实现自己的流来防止线程化。 但不管怎样:线程都不错,只要你不过度使用它。 |
![]() |
7
1
我知道你在追求什么-我已经解决了同样的问题,在这种情况下,服务器后面的伪装防火墙与动态IP。我用了一个免费的小程序, javaProxy 提供解决方案。它使服务器看起来像一个客户机套接字—在内部,它仍然是一个服务器,但是javaProxy提供了一个转发程序—在本例中是我的应用程序—从服务器创建客户机连接。它还提供了中间代理(在本例中为中间服务器)将两个客户端连接在一起—从服务器转发的客户端套接字和从尝试连接到服务器的实际客户端发送的客户端套接字。 中间服务器位于防火墙之外的已知IP上。(尽管我们可以假装不使用服务器套接字,但每个连接都必须包含一个客户机和一个服务器端,因此我们确保中间服务器位于客户机可以访问的IP上。)在我的例子中,我使用了一个简单的托管提供程序,它允许我从shell运行java。 通过这种设置,我可以访问远程桌面和其他运行在具有动态IP的NAT防火墙后面的服务,也可以访问位于具有动态IP的NAT后面的家庭计算机。我只需要知道中间服务器的IP地址。 至于线程,javaproxy库几乎肯定是使用线程在客户机套接字之间泵送数据来实现的,但是这些线程在阻塞等待I/O时不会消耗任何CPU资源(或电源)。当java 7发布并支持异步I/O时,每个客户机套接字对将不需要一个线程,但是更重要的是性能和避免对最大线程数(堆栈空间)的限制,而不是功耗。 至于自己在同一进程中用两个客户端套接字来实现这一点,只要java依赖于阻塞I/O,就需要使用线程。模型是从读端拉到写端,因此需要一个线程从读端拉。(如果我们从读取端进行推送,即异步i/O,那么每个套接字对就不需要一个专用线程。) |
![]() |
8
0
为什么我们需要一个中间服务器?如果您只想公开VNCServer。为什么不试试下面这种架构
在本例中,MyApp既充当客户机(对于VNCServer)又充当服务器(对于用户)。因此,您必须在MyApp中实现客户端和服务器套接字,然后中继数据。 编辑: 要与VNCServer通信,MyApp需要知道VNCServer的IP。用户将只与MyApp通信,只需要知道MyApp的IP地址。用户不需要VNCServer的ip地址。 |
![]() |
9
0
在C中你可以打电话 插座对(2) 为了获得一对连接的套接字,但是我不确定java是否有任何内置的方法来做同样的事情。 |
![]() |
10
0
一般来说,客户机TCP套接字有两端(本地和远程),服务器TCP套接字有一端(因为它正在等待客户机连接到它)。当客户机连接到服务器时,服务器会在内部生成一个客户机套接字,以形成一对表示通信通道的连接的客户机套接字;这是一对,因为每个套接字从一端查看通道。这就是TCP的工作原理(在高层次上)。 不能让两个客户机套接字在TCP中相互连接,因为低级连接协议不是这样工作的。(在Unix中可以用这种方式创建一对连接的套接字,但它在Java中没有公开,它们不是TCP套接字) 可以 你要做的是一旦你接受了一个连接就关闭服务器套接字;对于简单的情况,这可能就足够了。 当然,UDP套接字是不同的,但是它们处理的是数据报而不是流。这是一种完全不同的沟通模式。 |
![]() |
11
0
如果你想要一个
希望这有帮助。 |
![]() |
12
-1
基于连接的套接字通信的经典Java方法是建立一个 在一个已知的IP和端口和块上,它的accept调用(在成功连接尝试之后)返回一个新的 插座 具有由实现确定的端口(不同于 服务端 的端口)。通常将返回的套接字传递给实现 可运行的 . 处理程序暂时与特定连接相关联。处理程序可以重用,并且通常在连接的生命周期内与特定线程相关联。经典的javasocketio的阻塞特性使得连接由同一线程服务的两个套接字非常困难。 可运行的 要求被删除,即处理程序和 服务器套接字接受 呼叫将推迟到当前连接关闭。 NIO公司 您可以使用选择器机制轻松地同时处理同一线程上的多个连接。这是最重要的特征之一 ,非阻塞I/O将线程与连接解耦(允许由小线程池处理非常多的连接)。 纳特 服务或某种代理将公共IP连接到私有IP。 |
|
user29759326 · 如何返回递归函数中的最后一个值? 4 月前 |
|
malife89 · 将java中的字符串读取为正确的日期格式 4 月前 |
![]() |
Tim · 在java中,有没有更快的方法将字节数组写入文件? 4 月前 |
![]() |
rudraraj · java中未声明最终变量 4 月前 |
![]() |
Bala Ji · 以下BFS的实施效率如何? 4 月前 |