У меня интересная проблема с функцией 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, недействителен, что имеет несколько возможные причины:
- fd где-то уже закрыт.
- 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
может остаться в поврежденном состоянии.