簡體   English   中英

為什么我收到錯誤的文件描述符錯誤?

[英]Why am I getting a bad file descriptor error?

我正在嘗試編寫一個像客戶端一樣的短程序,例如telnet。 我從用戶輸入中收到如下信息:www.google.com 80(端口號)和 /index.html 但是,我遇到了一些錯誤。 當我寫一些調試信息時,它說我有一個錯誤的文件描述符並且在文件描述符 100 消息大小 = 0 上讀取失敗。

struct hostent * pHostInfo;
struct sockaddr_in Address;
long nHostAddress;
char pBuffer[BUFFER_SIZE];
unsigned nReadAmount;
int nHostPort = atoi(port);

vector<char *> headerLines;
char buffer[MAX_MSG_SZ];
char contentType[MAX_MSG_SZ];

int hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (hSocket == SOCKET_ERROR)
{
  cout << "\nCould Not Make a Socket!\n" << endl;
  return 1;
}
pHostInfo = gethostbyname(strHostName);
memcpy(&nHostAddress,pHostInfo -> h_addr, pHostInfo -> h_length);

Address.sin_addr.s_addr = nHostAddress;
Address.sin_port=htons(nHostPort);
Address.sin_family = AF_INET;

if (connect(hSocket, (struct sockaddr *)&Address, sizeof(Address)) == SOCKET_ERROR)
{
  cout << "Could not connect to the host!" << endl;
  exit(1);
}
char get[] = "GET ";
char http[] = " HTTP/1.0\r\nHost: ";
char end[] = "\r\n\r\n";
strcat(get, URI);
strcat(get, http);
strcat(get, strHostName);
strcat(get, end);
strcpy(pBuffer, get);
int len = strlen(pBuffer);
send(hSocket, pBuffer, len, 0);
nReadAmount = recv(hSocket,pBuffer, BUFFER_SIZE, 0);
//Parsing of data here, then close socket
if (close(hSocket) == SOCKET_ERROR)
{
  cout << "Could not close the socket!" << endl;
  exit(1);
} 

謝謝!

您的代碼中有緩沖區溢出 您試圖將一堆字符數組一起分配到一個只有 5 個字節長的緩沖區中:

char get[] = "GET ";  // 'get' is 5 bytes long
char http[] = " HTTP/1.0\r\nHost: ";
char end[] = "\r\n\r\n";
strcat(get, URI);  // BOOM!
strcat(get, http);
strcat(get, strHostName);
strcat(get, end);

這可能會覆蓋您的局部變量hSocket ,從而導致“錯誤的文件描述符錯誤”。

由於您使用的是 C++(您的代碼中有一個vector ),因此只需使用std::string而不是 C 字符數組,這樣您就不必擔心內存管理。

嘗試寫入您沒有寫入權限的位置時,可能會遇到“錯誤的文件描述符”的另一個原因。 例如,在 Windows 環境下嘗試使用wget下載內容時:
Cannot write to 'ftp.org.com/parent/child/index.html' (Bad file descriptor).

“壞文件描述符”的另一個原因可能是意外嘗試將 write() 寫入只讀描述符。 我堅持了一段時間,因為我一直在尋找第二個 close() 或緩沖區溢出。

另一種情況可能是目標輸出文件名包含文件系統不允許的字符。 例如,假設您在 Linux 計算機上運行 wget 命令,並且目標路徑是使用 NTFS 格式化的外部硬盤驅動器。 Linux Ext4 文件系統將允許諸如“?”之類的字符,但 NTFS 文件系統不允許。 wget 的默認行為是將目標文件夾命名為指定的 url。 如果 url 包含像 ':' 這樣的特殊字符,NTFS 將不接受該字符,從而導致錯誤“文件描述符錯誤”。 您可以使用 --no-host-directories 參數在 wget 中禁用此默認行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM