当前位置: 首页 > 知识库问答 >
问题:

多线程套接字通信中的场景

陶征
2023-03-14

我有一个socket客户端应用程序,在应用程序启动期间,会创建socket(与服务器建立连接),并启动两个并行运行的线程。

Thread-1:使用read方法连续读取套接字(块,直到收到数据)

Thread-2:连续写入数据。

在写入套接字时,如果线程2接收到IO异常,那么它会丢弃现有的套接字并创建新的套接字并开始通信。由于线程2丢弃套接字,线程1接收空指针异常。我们有什么应对策略吗

共有2个答案

隆宏爽
2023-03-14

您开始遇到与系统设计的proactor风格相关的问题。解决这个问题需要两个线程之间进行一些通信。选择这种交流方式会让事情变得一团糟。它必须能够阻止thread1尝试读取套接字。我不太擅长Java,但在C中,这意味着使用信号。

我建议你避免使用信号,即使Java中也有类似的信号。

一个更好的选择是,在调用select()(或任何Java等价物)时阻止thread1,等待套接字和管道。当Thread2想要关闭套接字时,它会写入管道,thread1从select()返回,在管道中写入对Thread2的响应,并再次调用select(),但只在管道上调用。Thread2读取该响应,关闭套接字,打开一个新的套接字,然后沿管道发送其他内容以再次唤醒thread1,thread1现在可以返回到select(),但这次是在管道和新套接字上。这实现了thread1和thread2之间的执行会合;thread2可以关闭旧插座并打开新插座,因为它知道(通过管道通信)thread1何时不使用插座。

这就有些凌乱了。也变得更像Reactor设计模式。在这种情况下,也可以只使用一个线程来选择是否将套接字作为它正在执行的任何循环的一部分来读取。这个单线程将在数据可用时读取数据,而不是希望数据到达时进行阻塞读取。如果套接字写入出错,需要替换套接字,它只是这样做;没有其他线程可以同步。假设您的套接字连接到网络上的远程服务器(而不是同一台机器上的服务),以太网的速度仍然是主要瓶颈;Reactor式系统也不会慢。

一般来说,使用reactor系统样式处理网络故障要容易得多,因为没有线程致力于执行其他线程知道不合适的操作。不幸的是,大多数编程环境都是proactor,例如Windows、Boost ASIO、RabbitMQ等。在出现问题之前,proactor系统是正常的,在这之后,通常有必要扔掉整个过程,因为对于程序员来说,整理所有错误的回调和异步IOs很容易变得极其复杂。

一种选择是如果可以的话使用ZeroMQ。这要求您在任何地方都使用ZeroMQ(也使用服务器),但它使处理网络问题变得容易得多。这是一个Reactor,而不是一个促发剂。

鄢禄
2023-03-14

线程2需要在关闭套接字之前关闭套接字进行输入。这将导致线程接收并结束流,这将导致它关闭套接字并退出。然后线程2可以创建另一个套接字并启动另一个读取线程。

 类似资料:
  • 这是我的客户端和服务器的代码。 class Client1{Client1(int no){try{String message;message=“Hello this is client”+no;byte[]b=message.getBytes();DatagramPacket dp=new DatagramPacket(b,b length,inetAddress.getLocalHost()

  • 我有一个类似的问题,但是我知道当我要求阅读一行时,发件人应该发送一个行尾。 让我困惑的是,在调试中,它是有效的。可能是因为我在调试时跳过的顺序(直到现在我都不知道这会有什么不同),但我想更好地理解它。 我已经使用线程,但不是很多。 这是我的服务器类: 线程(基于此) 和客户: 它似乎在某个地方进入了死锁,出于某种原因,除非在调试中运行,否则永远不要在向客户端发送数据的服务器类上输入该死锁 (顺便说

  • 为了实现这一点,我使用了队列/线程池机制。最初,我创建一个固定数量线程的池,并有一个队列datastructure来存储客户机地址。这个队列在所有线程之间共享,因此我使用“互斥”来锁定/解锁这个队列。在主服务器线程中,我创建一个套接字,将其绑定到全局端口/地址,然后在“recvfrom”调用上阻止服务器。任何希望与服务器通信的客户端都会向侦听全局端口地址的主线程服务器发送“HI”消息。主服务器线程

  • 问题内容: 如果我有多个Java线程同时写入同一Socket实例,这会影响从同一套接字读取的对象的完整性吗?即,对象的内容是否会被弄乱等等。对象的顺序可以是随机的。 问题答案: 通常,没有任何保证。一点点不同的对象很可能最终会在电线上交错,使结果难以辨认。 因此,您需要提供外部同步。 有趣的是,即使在OS级别进行单个套接字写入也不一定是原子操作。有关进一步的讨论,请参见注意sendmsg()系列函

  • 问题内容: 我正在尝试在C中创建一个多线程服务器- 客户端文件传输系统。有些客户端将发送或列出或做其他选择(在交换机的情况下,您可以看到),而服务器则存储文件并提供大量服务客户。 就我所知,多线程意识形态确实很困难。它需要太多的经验而不是知识。我已经在该项目上工作了一个多星期,但我一直无法解决这些问题。 有4个选择:第一个是在其目录中列出客户端的本地文件,第二个是在客户端和服务器之间传输的列表文件

  • 我是python套接字编程的初学者,正在尝试编写一个与联网家庭自动化设备(GlobalCache GC100)接口的库 我既需要通过TCP不断监听来自该硬件的传感器状态变化事件,也需要能够在用户发起的时间发送set_state命令(trip relays),而没有明显的延迟。 我有一个循环,它执行来拾取状态更改事件。这通常会超时()并继续到下一个循环迭代,直到设备推送状态更改数据。 我是想做套接字