Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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_Sockets_Networking_Tcp_Network Programming - Fatal编程技术网

消息传递的java网络编程协调

消息传递的java网络编程协调,java,sockets,networking,tcp,network-programming,Java,Sockets,Networking,Tcp,Network Programming,我有两个进程在不同的机器上运行,它们通过TCP套接字进行通信。 这两个进程都有既充当服务器又充当客户端的代码。 也就是说,ProcessA打开了在portX绑定的服务器套接字,ProcessB打开了在portY绑定的服务器套接字。 ProcessA打开一个客户端套接字以连接ProcessB并开始作为客户端发送消息 和接收响应(当然是通过相同的tcp连接)。 ProcessB一旦接收到消息并对其进行处理,就会发送响应,但也可以通过第二个tcp连接发送消息,即ProcessB已将客户端套接字打开到P

我有两个进程在不同的机器上运行,它们通过TCP套接字进行通信。
这两个进程都有既充当服务器又充当客户端的代码。
也就是说,ProcessA打开了在portX绑定的服务器套接字,ProcessB打开了在portY绑定的服务器套接字。
ProcessA打开一个客户端套接字以连接ProcessB并开始作为客户端发送消息 和接收响应(当然是通过相同的tcp连接)。
ProcessB一旦接收到消息并对其进行处理,就会发送响应,但也可以通过第二个tcp连接发送消息,即ProcessB已将客户端套接字打开到ProcessA的portX。
因此,消息流通过两个不同的tcp连接。
我的问题如下:理所当然地认为这种“架构”不能改变,必须保持原样:
我遇到的问题是,消息通过ProcessB已打开客户端套接字的tcp连接间歇性地从ProcessB发送到ProcessA,在消息作为响应通过ProcessA已作为客户端套接字连接的tcp连接从ProcessB发送到ProcessA之前到达ProcessA。
也就是说,两种流动都会发生

(1)  
ProcessA ---->(msg)----> ProcessB(PortY)  (TCP1)
ProcessB does processing   
ProcessB(portY)--->(response)----->ProcessA (TCP1)  
ProcessB--->(msg)----->ProcessA(portX)  (TCP2)

(2)  
ProcessA ---->(msg)----> ProcessB(PortY)  (TCP1)
ProcessB does processing   
ProcessB--->(msg)----->ProcessA(portX)  (TCP2)
ProcessB(portY)--->(response)----->ProcessA  (TCP1)
编辑(在ejp请求后) 在消息send as reply from server portY of ProcessB到达ProcessA之前,我如何强制/确保ProcessB不通过ProcessB的客户端套接字打开到ProcessA的服务器端口X的连接发送消息?也就是说,只有上述流程(1)。
请注意,processB是多线程的,并且处理过程非常复杂

更新:
也许这是我的误解,但当一个进程通过套接字发送数据,并将控制返回给应用程序时,这并不意味着接收方已经收到了数据。 所以,如果一个进程通过两个套接字发送数据,操作系统是否存在竞争条件

更新2
从维杰·马修那里得到答案后:
如果我按照建议进行了锁定,是否可以保证操作系统(即IP层)将按顺序发送数据?即完成一次传输,然后发送下一次?或者我会将它们多路复用,并有相同的问题


谢谢

显而易见的解决方案是:

LockObject lock;

ProcessA ---->(msg)----> ProcessB(PortY)

// Processing the request and sending its response 
// makes a single transaction.
synchronized (lock) {
    ProcessB does processing   
    ProcessB(portY)--->(response)----->ProcessA (TCP1)
}

// While the processing code holds the lock, B is not
// allowed to send a request to A.
synchronized (lock) {
    ProcessB--->(msg)----->ProcessA(portX)  (TCP2)
}

显而易见的问题是,你为什么在意?如果您有需要在两端同步的操作,请这样做。不要期望TCP为您做这件事,这不是它的目的。

同步问题可能不在TCP协议中,而是在线程处理程序中选择消息到达时唤醒哪个线程。根据您问题的性质,我理解PortX“(Msg)”是在PortY”(响应)之后很快发送的。这意味着线程处理程序有时可以选择将唤醒两个侦听线程中的哪一个

一种简单但丑陋且不完整的解决问题的方法是在响应和下一条消息之间插入一个短睡眠。睡眠时间必须足够长,以确保在收到下一条消息之前,另一个进程已被响应唤醒。这种方式是不完整的,因为尽管您正在增加正确同步处理的更改,但操作系统负载和网络拥塞等问题总是会将消息推回到响应后面。然后你又回到了起点。另一个缺点是睡眠浪费时间,会降低最大吞吐量。只是不太经常。所以

为了完全解决这个问题,您需要让每个套接字侦听器知道它刚刚收到的消息是否是下一个要处理的消息,或者是否可能有必须首先处理的早期消息。通过对每个进程发送的所有消息进行顺序编号来完成此操作。然后接收过程知道是否缺少任何内容

您必须为每个套接字上的侦听器想出一种方法,以便它们之间进行协商,以确保接收到的消息按照传输顺序进行处理。有许多实际的解决方案,但它们在抽象的概念层面上都是一样的

线程1: A) ProcessA(PortX)线程接收消息并唤醒。
B) 如果序列号指示缺少消息,则 B1)在进程A(端口)上同步并等待()。 B2)醒来时,返回B) C) {没有消息丢失}处理该消息。 D) 回到A)

线程2: A) ProcessA(PortY)接收响应并唤醒。 B) 处理响应。 C) notifyAll()。 D) 回到A)

最通用的实用解决方案可能涉及一个套接字侦听器实例,将所有新消息添加到PriorityQueue,以便最早发送的消息始终到达队列的头部。然后线程1和线程2都可以等待该实例,直到它们可以处理的消息到达

一个更简单但可扩展性较差的解决方案是让每个线程自己监听并等待(响应)处理程序在处理后发出通知


祝你好运,尽管经过这么长时间,它可能已经解决了。

可能是我的误解,但当processB将数据交给操作系统通过套接字发送时,控制是否会在另一端收到数据后从操作系统返回到应用程序?不,所以OS可以缓冲数据,ProcessB将移动到第二个锁,然后通过第二个套接字传递数据。所以在2个发送中仍然会有一些比赛条件,对吗?你能澄清一下吗?你的意思是B不应该通过端口X向A发送下一个请求,直到A通过端口X收到上一个回复?所以Y端口在这里完全不相关?@ejp:有两个tcp连接。在A收到上一条消息(由A发送给在portY中侦听的B)的回复之前,B不应通过portX(在A中打开)向A发送消息。这是否更清楚?