Ошибка шины TCP в Linux

У меня есть клиент-серверное приложение, и я использую сокеты tcp. По запросу send() со стороны клиента я всегда получаю ошибку шины, и программа завершается. Теперь я сделал небольшой поиск в Википедии, и статья приписывает ошибки шины (несуществующему физическому адресу, невыровненному доступу к памяти и доступу к усеченному файлу mmapped). Моя структура, которую я отправляю, состоит всего из трех целых чисел и экземпляра перечисления, поэтому я не думаю, что выравнивание является проблемой. Вот соответствующий фрагмент кода:

typedef struct _commsg
{
    RequestType requestType;
    int client_pid;
    int request_id;
    int sector;
}ComMsg; 

в основном:

/* Create a reliable, stream socket using TCP */
if ((sock_id = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    DieWithError("socket() failed\n");

/* Construct the server address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr));     /* Zero out structure */
echoServAddr.sin_family      = AF_INET;             /* Internet address family */
echoServAddr.sin_addr.s_addr = inet_addr(loopback_addr);   /* Server IP address */
echoServAddr.sin_port        = htons(SERVER_PORT); /* Server port */

/* Establish the connection to the echo server */
if (connect(sock_id, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
    DieWithError("connect() failed");


if (send(sock_id, (void *)&_commsg, sizeof(ComMsg), 0) != sizeof(ComMsg))
    DieWithError("send() sent a different number of bytes than expected");

И на стороне сервера:

recv(clntSocket_fd, &_commsg, sizeof(ComMsg), 0);

Заранее спасибо.


person Aladdin    schedule 23.02.2012    source источник
comment
Либо что-то важное отсутствует, либо ваш компилятор действительно странный!   -  person Donal Fellows    schedule 23.02.2012
comment
действительны ли идентификаторы сокетов? а что такое _commsg? пожалуйста, предоставьте больше кода.   -  person Karoly Horvath    schedule 23.02.2012
comment
_commsg — это структура, которую я указал вверху листинга кода. Мне нужно &_commsg, потому что send принимает указатель на данные, которые вы пытаетесь отправить. Кстати, я также проверяю идентификатор носка, прежде чем делать это, поэтому процесс создает действительный socket_id.   -  person Aladdin    schedule 23.02.2012
comment
@Aladdin: это даже не должно компилироваться ..   -  person Karoly Horvath    schedule 23.02.2012
comment
Хм, сообщение было удалено, но у меня есть локальная переменная с именем ComMsg _commsg внутри main. Вот почему он компилируется. Извините за путаницу. Что касается endianess, я использую петлевой адрес для целей этого проекта, поэтому у меня не должно возникнуть проблем с отправкой структур.   -  person Aladdin    schedule 23.02.2012
comment
не могли бы вы показать этот _commsg ?   -  person Karoly Horvath    schedule 25.02.2012


Ответы (3)


Вы компилируете приложение с включенными полными предупреждениями (например, с помощью gcc, -Werror)? Вам следует. Ошибка шины почти наверняка означает, что вы обращаетесь к неверному указателю, нарушаете API в параметрах, которые вы передаете функции, и т. д. Попробуйте скомпилировать с включенными полными предупреждениями, аккуратно исправьте каждую ошибку, которую вы видите, и посмотрите, решит ли это вашу проблему. .

Кстати, с сокетами TCP чтение(2) и запись(2) используются чаще, чем send(2) и recv(2).

person Perry    schedule 24.02.2012

Как указано на странице руководства send (2) «Единственная разница между send () и write (2) заключается в наличии флагов. С нулевым аргументом флагов send () эквивалентен write (2)»

Как утверждает Стивенс в своей книге по сетевому программированию Unix. «Потоковые сокеты (например, сокеты TCP) демонстрируют поведение с функциями чтения и записи, которое отличается от обычного файлового ввода-вывода. Чтение или запись в потоковом сокете может вводить или выводить меньше байтов, чем запрошено»

Следовательно, вместо этого может потребоваться проверить наличие ошибок следующим образом:

  if (send(sock_id, (void *)&_commsg, sizeof(ComMsg), 0) < 0)

и не проверяет отправленные байты. Возможно, вы закрываете свое приложение, хотя на самом деле в нем нет проблем.

Кроме того, отправка структуры по сети обычно не является хорошей идеей, так как вы можете столкнуться с проблемами, связанными с порядком байтов, при подключении к другим системам, отличным от вашей, предпочтительный способ - работа со строками байтов.

person quicoju    schedule 23.02.2012

Запуск вашего клиента с strace -esend или с gdb может быть просветленным.

person Armali    schedule 13.03.2014