Ошибка шины TCP в Linux - PullRequest
       20

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

0 голосов
/ 23 февраля 2012

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

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);

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

Ответы [ 3 ]

1 голос
/ 25 февраля 2012

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

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

0 голосов
/ 13 марта 2014

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

0 голосов
/ 23 февраля 2012

Как указано в справочной странице send (2) "Единственная разница между send () и напишите (2) наличие флагов. С аргументом нулевого флага, send () эквивалентно write (2) "

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

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

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

и не проверяет отправленные байты. Вы можете закрыть свою заявку когда на самом деле в этом нет проблемы.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...