Проблема синхронизации может заключаться не в протоколе TCP, а в обработчике потока, который выбирает, какой поток активировать при поступлении сообщений.Из характера вашего вопроса я понимаю, что PortX "(Msg)" отправляется очень быстро после PortY "(Ответ)".Это означает, что обработчик потока может иногда иметь выбор относительно того, какой из двух потоков прослушивания он будет активировать.
Простой, но уродливый и неполный способ решения проблемы - вставить короткий сон междуответ и следующее сообщение.Спящий режим должен быть достаточно длинным, чтобы быть уверенным, что другой процесс проснется до ответа до получения следующего сообщения.Этот способ неполон, потому что, хотя вы увеличиваете изменения, связанные с правильной синхронизацией обработки, такие проблемы, как загрузка ОС и перегрузка сети, всегда могут привести к тому, что ваше сообщение окажется позади вашего ответа.А потом ты вернулся туда, откуда начал.Другое уродство заключается в том, что сон тратит время и снижает вашу максимальную пропускную способность.Просто реже.Итак ...
Чтобы полностью решить проблему, необходимо, чтобы каждый прослушиватель сокетов знал, является ли только что полученное сообщение следующим обрабатываемым, или могут существовать более ранние сообщения, которые должныобрабатываться в первую очередь.Сделайте это путем последовательной нумерации всех сообщений, отправляемых каждым процессом.Затем процесс приема узнает, что-то отсутствует.
Вам нужно будет придумать способ, которым слушатели на каждом сокете будут взаимодействовать между собой, чтобы гарантировать, что полученные сообщения обрабатываются в порядке передачи.Существует несколько практических решений, но все они равны на абстрактном, концептуальном уровне.
РЕЗЬБА 1: A) Поток ProcessA (PortX) получает сообщение и пробуждается.
B)ЕСЛИ порядковый номер указывает на наличие пропущенного сообщения, ТО B1) синхронизируется на ProcessA (PortY) и wait ().B2) После пробуждения вернитесь к B) C) {сообщение не пропущено} Обработайте сообщение.D) Назад к A)
THREAD 2: A) ProcessA (PortY) получает ответ и просыпается.Б) Обработка ответа.В) уведомить все ().D) Назад к A)
Наиболее общие практические решения, вероятно, будут включать в себя один экземпляр прослушивателя сокетов, добавляющий все новые сообщения в PriorityQueue, так что самые ранние отправленные сообщения всегда отправляются в начало очереди.Затем поток 1 и поток 2 могут ожидать в этом экземпляре, пока не прибудет сообщение, которое они могут обработать.
Более простое, но менее расширяемое решение состояло бы в том, чтобы каждый поток выполнял свое собственное прослушивание и ожидание с (ответом)обработчик уведомляет после обработки.
Удачи с ним, хотя по прошествии этого времени он, вероятно, уже решен.