Надеюсь, окончательное обновление: -)
На основании вашего последнего обновления Centos упаковывает ваши структуры на уровне байтов, а CygWin - нет. Это вызывает проблемы с выравниванием. Я не уверен, почему в случае с CygWin-to-CygWin возникают проблемы, так как там должны быть одинаковые отступы, но я могу рассказать вам, как исправить другой случай.
Используя код, который я дал ранее:
#include <stdio.h>
typedef struct {
unsigned char _array[28];
long long _sequence;
unsigned char _type;
unsigned char _num;
short _size;
} tType;
int main (void) {
tType t[2];
printf ("%d\n", sizeof(long));
printf ("%d\n", sizeof(long long));
printf ("%d\n", sizeof(tType));
printf ("%p\n", &(t[0]._array));
printf ("%p\n", &(t[0]._sequence));
printf ("%p\n", &(t[0]._num));
printf ("%p\n", &(t[0]._size));
printf ("%p\n", &(t[1]));
return 0;
}
Если вы не хотите заполнять, у вас есть два варианта. Первый - это реорганизовать вашу структуру, чтобы поставить более ограниченные типы впереди:
typedef struct {
long long _sequence;
short _size;
unsigned char _array[28];
unsigned char _type;
unsigned char _num;
} tType;
, что дает вам:
4
8
40
0x22cd42
0x22cd38
0x22cd5f
0x22cd40
0x22cd60
Другими словами, каждая структура составляет ровно 40 байтов (8 для последовательности, 2 для размера, 28 для массива и 1 для типа и числа). Но это может быть невозможно, если вы хотите, чтобы это было в определенном порядке.
В этом случае вы можете заставить выравнивания быть на уровне байтов с помощью:
typedef struct {
unsigned char _array[28];
long long _sequence;
unsigned char _type;
unsigned char _num;
short _size;
} __attribute__ ((aligned(1),packed)) tType;
aligned(1)
устанавливает его в байтовое выравнивание, но это не сильно повлияет, поскольку объектам не нравится, когда их выравнивание уменьшается. Для этого вам также нужно использовать packed
.
Делая это, вы получаете:
4
8
40
0x22cd3c
0x22cd58
0x22cd61
0x22cd62
0x22cd64
Более ранняя история процветания:
Ну, так как я wget
и ftp
огромных файлов просто отлично от CygWin, мои навыки психической отладки говорят мне, что это скорее проблема с вашим кодом, чем с программным обеспечением CygWin.
Другими словами, в отношении предложения «пакеты повреждены между уровнем, который просматривает Wireshark, и самой программой», я бы серьезно посмотрел на верхний предел этой шкалы, а не на нижний::)
Обычно это тот случай, когда вы предполагали, что read
будет получать весь отправленный пакет, а не биты за раз, но, не видя рассматриваемого кода, это довольно дикое предположение.
Убедитесь, что вы проверяете возвращаемое значение из read
, чтобы увидеть, сколько байтов фактически принимается. Кроме того, опубликуйте код, отвечающий за read
, чтобы мы могли провести более углубленный анализ.
Судя по вашему опубликованному коду, все выглядит хорошо. Единственное, что я могу предложить, это убедиться, что буферы, которые вы передаете, достаточно велики и, даже если они есть, убедитесь, что вы печатаете их сразу после возврата, если какой-то другой фрагмент кода повреждение данных.
На самом деле, перечитывая ваш вопрос более внимательно, я немного растерялся. Вы заявляете, что у вас одинаковая проблема с кодом вашего сервера в Linux и CygWin, но говорите, что он работает на Centos.
На данный момент мой единственный совет - ставить отладочные операторы printf
в той функции, которую вы показали, например, после вызовов select
и read
для вывода соответствующих переменных, включая got
и buf
после их изменения, а также в каждом пути кода, чтобы вы могли видеть, что он делает. А также выгрузите всю структуру побайтно в конце отправки.
Это, мы надеемся, сразу покажет вам, в чем проблема, тем более что у вас, кажется, есть данные, отображаемые не в том месте.
И убедитесь, что ваши типы совместимы на обоих концах. Под этим я подразумеваю, что если long long
разных размеров на двух платформах, ваши данные будут смещены.
Хорошо, проверьте выравнивание на обоих концах, скомпилируйте и запустите эту программу на обеих системах:
#include <stdio.h>
typedef struct {
unsigned char _array[28];
long long _sequence;
unsigned char _type;
unsigned char _num;
short _size;
} tType;
int main (void) {
tType t[2];
printf ("%d\n", sizeof(long));
printf ("%d\n", sizeof(long long));
printf ("%d\n", sizeof(tType));
printf ("%p\n", &(t[0]._array));
printf ("%p\n", &(t[0]._sequence));
printf ("%p\n", &(t[0]._num));
printf ("%p\n", &(t[0]._size));
printf ("%p\n", &(t[1]));
return 0;
}
На моем CygWin я получаю:
4 long size
8 long long size
48 structure size
0x22cd30 _array start (size = 28, padded to 32)
0x22cd50 _sequence start (size = 8, padded to 9???)
0x22cd59 _type start (size = 1)
0x22cd5a _size start (size = 2, padded to 6 for long long alignment).
0x22cd60 next array element.
Единственный нечетный бит - это заполнение перед _type, но это, конечно, верно, хотя и неожиданно.
Проверьте выходные данные Centos, чтобы убедиться, что они несовместимы. Однако ваше утверждение о том, что CygWin-to-CygWin не работает, несовместимо с этой возможностью, поскольку размеры и размеры будут совместимы (если ваш код отправки и получения не скомпилирован по-другому).