为什么会出现坏的文件描述符错误?

4

我正在尝试编写一个类似于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);
} 

感谢!
4个回答

8
你的代码中存在缓冲区溢出。你尝试将一些字符数组分配到一个只有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++(代码中有一个向量),所以只需使用std::string而不是字符的C数组即可,这样你就不必担心内存管理。

3
另一个导致“坏文件描述符”的原因是尝试写入没有写入权限的位置。例如,在Windows环境中尝试使用wget下载内容时:
无法写入“ftp.org.com/parent/child/index.html”(坏文件描述符)。

1

另一种情况可能是目标输出文件名包含文件系统不允许的字符。例如,假设您在Linux计算机上运行wget命令,并且目标路径是格式化为NTFS的外部硬盘。Linux Ext4文件系统将允许使用诸如“?”之类的字符,但NTFS文件系统不会。wget的默认行为是将目标文件夹命名为指定的URL。如果URL包含特殊字符(如“:”),则NTFS将不接受该字符,导致错误“Bad file descriptor”。您可以使用--no-host-directories参数禁用wget的此默认行为。


0

'坏文件描述符'的另一个原因可能是意外地尝试向只读描述符写入write()。我曾经被卡在这个问题上一段时间,因为我一直在寻找第二个close()或缓冲区溢出。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接