Я тестировал TCP-клиент/слушатель.TCP не получает отправленные данные
Мой тест открывает 10 клиентов и принимает их правильно. Затем он отправляет некоторые данные через каждый из них. Только после правильно отправьте все данные, которые он пытается получить в противоположную сторону.
Здесь Вы можете найти результаты по strace для первых 4 подключений. getpeername() используется для проверки соединения на каждой стороне сразу после каждого отправьте и получите. Я уже пытался выполнить прием внутри петли, пока он не получит что-то с без эффекта. Поэтому для ясности здесь я показываю результаты для одиночных recv за соединение.
send(4, "abcdefghij", 10, 0) = 10
getpeername(4, {sa_family=AF_INET, sin_port=htons(1366), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
getpeername(5, {sa_family=AF_INET, sin_port=htons(44847), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
send(6, "abcdefghij", 10, 0) = 10
getpeername(6, {sa_family=AF_INET, sin_port=htons(1366), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
getpeername(7, {sa_family=AF_INET, sin_port=htons(44848), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
send(8, "abcdefghij", 10, 0) = 10
getpeername(8, {sa_family=AF_INET, sin_port=htons(1366), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
getpeername(9, {sa_family=AF_INET, sin_port=htons(44849), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
send(10, "abcdefghij", 10, 0) = 10
getpeername(10, {sa_family=AF_INET, sin_port=htons(1366), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
getpeername(11, {sa_family=AF_INET, sin_port=htons(44850), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
[...]
recv(5, "", 10, 0) = 0
getpeername(4, {sa_family=AF_INET, sin_port=htons(1366), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
getpeername(5, {sa_family=AF_INET, sin_port=htons(44847), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
recv(7, "abcdefghij", 10, 0) = 10
getpeername(6, {sa_family=AF_INET, sin_port=htons(1366), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
getpeername(7, {sa_family=AF_INET, sin_port=htons(44848), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
recv(9, "", 10, 0) = 0
getpeername(8, {sa_family=AF_INET, sin_port=htons(1366), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
getpeername(9, {sa_family=AF_INET, sin_port=htons(44849), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
recv(11, "abcdefghij", 10, 0) = 10
getpeername(10, {sa_family=AF_INET, sin_port=htons(1366), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
getpeername(11, {sa_family=AF_INET, sin_port=htons(44850), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
[...]
Примечания:
- Прием отправленных сообщений происходит только на четных соединений (клиент 0, клиент 2, клиент 4 ...).
- Каждое соединение использует блокирующий сокет, поэтому recv() должен ждать навсегда.
- Неудачные соединения возвращают 0 (упорядоченное выключение), но после проверки говорит мне, что соединение все еще открыто ... Правильно ли?
- Существует нет syscalls (например, для закрытия сокетов) между блоком отправки и блоком приема.
Мои вопросы:
Если соединение потеряно, и почему?
Когда 'recv' возвращает ноль, это означает, что другая сторона нормально закрыла соединение. Вам нужно будет посмотреть на другую сторону, чтобы понять, почему это произошло. –
«... но после проверки говорит мне, что соединение все еще открыто ...» Похоже, вы используете 'getpeername()' для проверки состояния соединения. Это не то, что делает 'getpeername()'. – keithmo
Нет «после проверки», который может сказать вам, что соединение по-прежнему открыто, когда оно отсутствует, и нет причин, по которым ваш код должен даже попытаться использовать его. Вы все равно не отправили никакого кода. – EJP