Неверный дескриптор файла с Linux Socket write () Неверный дескриптор файла C

На чтение
8 мин
Дата обновления
03.03.2026
Тип:Профессия
Формат:Самостоятельно с наставником
Бизнес-аналитик: тариф PRO
Курс Бизнес-аналитик: тариф PRO поможет вам стать ценным специалистом, который умеет извлекать ключевую информацию и принимать обоснованные решения на основе данных. Вы овладеете практическими навыками работы с анализом бизнес-процессов, подготовкой требований и проведением исследований, что откроет перед вами множество возможностей в карьере. В рамках курса вас ждут реальные кейсы, практические задания и поддержка экспертов, а по завершении вы получите сертификат, подтверждающий ваши компетенции.
129900 ₽259800 ₽
10825 ₽/мес рассрочка
Подробнее

У меня интересная проблема с функцией write (2). Функция PrepareResponseForSetCoordinates вызывает ошибку неверного файлового дескриптора при записи.

Вот строка с ошибкой: perror («ОШИБКА записи в сокет»); общий вывод: ОШИБКА записи в сокет: Плохой файловый дескриптор

Я уверен, что установил соединение, потому что PrepareResponseForConnectionTest работает как шарм.

Можете ли вы представить себе причину ошибки?

Когда я использую gcc в качестве компилятора, проблем не было. После этого из-за использования нескольких новых источников cpp я использую g ++ в качестве компилятора, и у меня есть эта ошибка.

С уважением

Вот мой код:

  #define MAX_PMS_MESSAGE_LEN (4096) unsigned char baCommBuffer [MAX_PMS_MESSAGE_LEN]; unsigned char PrepareResponseForSetCoordinates (void) {unsigned char baTempBuff [255] = {0};  unsigned short bCnt = 0, i = 0, bCsum = 0, bCnt2 = 0; time_t lEpochTime; time_t lSessionTime; memset (baTempBuff, 0, sizeof (baTempBuff)); memset (baCommBuffer, 0, sizeof (baCommBuffer)); bzer  baCommBuffer, MAX_PMS_MESSAGE_LEN); bzero (baTempBuff, sizeof (baTempBuff)); lEpochTime = время (NULL); baCommBuffer [bCnt ++] = START_CHAR; baCommBuffer [bCnt ++] = START_CHARint; baCommBuffer [bCnt ++] = START_CHARint;  , "% ld", (длинное без знака) lEpochTime); memcpy (baCommBuffer + bCnt, baTempBuff, 10); bzero (baTempBuff, sizeof (baTempBuff)); bCnt + = 10; baCommBuffer [bCntT ++] = PACKORET_SEPERAT_time;  (NULL); если (SPMSMessage.lSessionID) lSessionTime = SPMSMessage.lSessionID;  elselSessionTime = lEpochTime; sprintf ((char *) baTempBuff, "% ld", (беззнаковое длинное) lSessionTime); memcpy (baCommBuffer + bCnt, baTempBuff, 10); bzero (baTempBuff, sizeof (baTempCntBuff) = 10);  [bCnt ++] = PACKET_SEPERATOR; baCommBuffer [bCnt ++] = PMC_ID; baCommBuffer [bCnt ++] = PACKET_SEPERATOR; baCommBuffer [bCnt ++] = PMS_ID; baCommBuffer [bCnt ++] = PMS_ID; baCommBuffer [bCnt ++] = baCommBuffer [bCnt ++] = bCnt ++];  '; baCommBuffer [bCnt ++] =' P '; baCommBuffer [bCnt ++] = PACKET_SEPERATOR; baCommBuffer [bCnt ++] =' C '; baCommBuffer [bCnt ++] =' O '; baCommBuffer [bCnt ++] =' Ouff] = 'O';  'S'; baCommBuffer [bCnt ++] = PACKET_SEPERATOR; if (SPMSMessage.bParam == SET_COOR_CAM1_PARAM) {baCommBuffer [bCnt ++] = '2'; baCommBuffer [bCnt ++] = PACKET_SEPERATOR; bCnt ++] = PACKET_SEPERATOR;  = 'N'; baCommBuffer [bCnt ++] = 'E'; baCommBuffer [bCnt ++] = PARAMETER_SEPERATOR; baCommBuffer [bCnt ++] = 'A'; baCommBuffer [bCnt ++] = 'C'; baCommBuffer [bCnt} ++] else = 'K';  если (SPMSMessage. bParam == SET_COOR_CAM2_PARAM) {baCommBuffer [bCnt ++] = '2'; baCommBuffer [bCnt ++] = PACKET_SEPERATOR; baCommBuffer [bCnt ++] = 'T'; baCommBuffer [bCnt ++ '] =' W '; bCommBuffer [bCnt ++'] = 'W';  [bCnt ++] = PARAMETER_SEPERATOR; baCommBuffer [bCnt ++] = 'A'; baCommBuffer [bCnt ++] = 'C'; baCommBuffer [bCnt ++] = 'K';  } else {baCommBuffer [bCnt ++] = '1'; baCommBuffer [bCnt ++] = PACKET_SEPERATOR; baCommBuffer [bCnt ++] = 'N'; baCommBuffer [bCnt ++] = 'A'; baCommBuffer [bCnt ++] = 'Cuffer ++] =' Cuffer ++] = 'Cuffer ++] =' Cuffer ';  = 'К';  } baCommBuffer [bCnt ++] = PACKET_SEPERATOR; baCommBuffer [bCnt ++] = '*'; memset (baTempBuff, 0, sizeof (baTempBuff)); bCsum = CalculateCheckSum (baCommBuffer); sprintf ((char *) ", sprintf ((char *)",  bCsum); memcpy (baCommBuffer + bCnt, baTempBuff, 2); bzero (baTempBuff, sizeof (baTempBuff)); bCnt + = 2; baCommBuffer [bCnt ++] = PACKET_SEPERATOR; baCommBuffer [END_CHARnt ++] = bCARnt ++;  ifdef _DEBUG_DEEP_DETAILED if (EDebugDeepDetail  

}

Ниже вы можете увидеть код, который работает без ошибок:

  без знака  char PrepareResponseForConnectionTest (void) {unsigned char baTempBuff [20] = {0}; unsigned char bCnt = 0, i = 0, bCsum = 0; time_t lEpochTime; time_t lSessionTime; memset (baTempBuff, 0, sizeof (baTempBuff)  (baCommBuffer, 0, sizeof (baCommBuffer)); bzero (baCommBuffer, MAX_PMS_MESSAGE_LEN); bzero (baTempBuff, sizeof (baTempBuff)); lEpochTime = time (NULL); baCommBuffer = time (baCommBuffer);  [bCnt ++] = PACKET_SEPERATOR; sprintf ((char *) baTempBuff, "% ld", (беззнаковое длинное) lEpochTime); memcpy (baCommBuffer + bCnt, baTempBuff, 10); bzero (baTempBuff, sizeof (baTempBuff) = 10);  ; baCommBuffer [bCnt ++] = PACKET_SEPERATOR; lSessionTime = SPMSMessage. lSessionID;  sprintf ((char *) baTempBuff, "% ld", (unsigned long) lSessionTime); memcpy (baCommBuffer + bCnt, baTempBuff, 10); bzero (baTempBuff, sizeof (baTempBuff)); bCnt + = 10; bCommBuffer [  PACKET_SEPERATOR; baCommBuffer [bCnt ++] = PMC_ID; baCommBuffer [bCnt ++] = PACKET_SEPERATOR; baCommBuffer [bCnt ++] = PMS_ID; baCommBuffer [bCnt ++] = PACKET_SEPERATOR [bCnt ++] = PACKET_SEPERATOR; [bCnt ++] = PACKET_SEPERATOR; [bCnt ++]  bCnt ++] = 'P'; baCommBuffer [bCnt ++] = PACKET_SEPERATOR; baCommBuffer [bCnt ++] = 'C'; baCommBuffer [bCnt ++] = 'O'; baCommBuffer [bCnt ++] = 'N'; baCommBuffer [bCnt ++] = 'N'; baCommBuffer [bCnt ++];  baCommBuffer [bCnt ++] = PACKET_SEPERATOR; baCommBuffer [bCnt ++] = '1'; baCommBuffer [bCnt ++] = PACKET_SEPERATOR; baCommBuffer [bCnt ++] = 'A'; baCommBuffer '= baCommBuffer' = bCnt ++] = 'Cuff' ++;  baCommBuffer [bCnt ++] = PACKET_SEPERATOR; baCommBuffer [bCnt ++] = '*'; memset (baTempBuff, 0, sizeof (baTempBuff)); bCsum = CalculateCheckSum (baCommBuffer); sprintf ((char *) baT ", bCums, baT",  ); memcpy (baCommBuffer + bCnt, baTempBuff, 2); bzero (baTempBuff, sizeof (baTemp  Buff)); bCnt + = 2; baCommBuffer [bCnt ++] = PACKET_SEPERATOR; baCommBuffer [bCnt ++] = END_CHAR; baCommBuffer [bCnt ++] = END_CHAR;  if ((ETcpConnectionState == ETcpStateConnected) || (ETcpConnectionState == ETcpStateConnectedAndWaitingToWrite)) {if (write (sockfd, baCommBuffer, bCnt)  

Вот моя функция InitializeConnection и функция ConnectToServer:

   void InitializeTcpConnection (int argc, char * argv []) {int optval;  socklen_t optlen = sizeof (optval); ETcpConnectionState = ETcpStateNotConnected;  if (argc  h_addr, (char *) & serv_addr.sin_addr.s_addr, server-> h_length); //serv_addr.sin_port: unsigned short//htons преобразует беззнаковый короткий hostshort из байтового порядка хоста в сетевой порядок байтов serv_addr. sin_port = htons (порт);  ETcpConnectionState = ETcpStateWaitingForConnection;} int ConnectToServer (void) {if (connect (sockfd, (struct sockaddr *) & serv_addr, sizeof (serv_addr))  

Обычно, когда встречается «Плохой дескриптор файла», это означает, что дескриптор файла сокета, который вы передали в API, недействителен, что имеет несколько возможные причины:

  1. fd где-то уже закрыт.
  2. fd имеет неправильное значение, несовместимое со значением, полученным из socket ( ) api

У меня тоже была эта ошибка, моя проблема была в какой-то части кода, который я не закрыл дескриптор файла, а с другой стороны, я попытался открыть этот файл !! используйте системный вызов close (fd) после завершения работы с файлом.

1


Значение, которое вы передали в качестве дескриптора файла, недействительно. Он либо отрицательный, либо не представляет открытый в данный момент файл или сокет.

Таким образом, вы либо закрыли сокет перед вызовом write () , либо вы испортили значение ‘sockfd’ где-нибудь в вашем коде.

Было бы полезно отслеживать все вызовы close () , а значение ‘sockfd’ до вызовы write () .

Ваша техника печати только сообщений об ошибках в режиме отладки кажется мне полным безумием, и в любом случае вызов другой функции между системой call и perror () недопустимы, поскольку могут нарушить значение errno . В самом деле, в данном случае это могло быть так, и реальная основная ошибка может быть другой.



Получение ошибки «Плохой дескриптор файла» при использовании tar

Я пытаюсь создать tar для каталога с помощью этой команды «tar -cpSWf myfile.tar workdir; gzip myfile.tar», но Я получаю эту ошибку для некоторых файлов в каталоге workdir.

  tar: my/sub/dir/file1. oa: не удается найти 1536: неверный дескриптор файла  

Я запускаю ту же команду в другом каталоге, и такой ошибки нет. Причина в том, что файлы .oa повреждены или диск выходит из строя? Это обычная проблема при использовании tar? Есть ли способ исправить эту ошибку?


Вопросы

Это потому, что файлы .oa повреждены, или диск выходит из строя? Это обычная проблема при использовании tar? Есть ли способ исправить эту ошибку?

На самом деле не имеет значения, является ли эта проблема типичной или нет (я с ней раньше не сталкивался), я бы начал с попытка tar создать один файл и посмотреть, не удастся ли еще немного изолировать проблему, а также повторить ее.

  $ tar  -cpSWf somefile.tar my/sub/dir/file1.oa  

Кроме того, вы можете сохранить шаг, tar и сжать все сразу:

  $ tar zcpSWf somefile.tar.gz ...  

Я бы также посмотрел, чтобы вынуть SW временно переключается, чтобы увидеть, влияет ли это на вашу способность tar и эти проблемные файлы.

Если эти ошибки являются предупреждением о наличии битых секторов на жестком диске вам может потребоваться запустить fsck или использовать такой инструмент, как HDAT2, чтобы попытаться восстановить любые поврежденные сектора. Однако в результате этих ремонтных работ файл .oa может остаться в поврежденном состоянии.