简体   繁体   中英

Why am I getting a bad file descriptor error?

I am trying to write a short program that acts like a client, like telnet. I receive from the user input like so: www.google.com 80 (the port number) and /index.html However, I get some errors. When I write some debug information, it says that I have a bad file descriptor and Read Failed on file descriptor 100 messagesize = 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);
} 

Thanks!

You have a buffer overrun in your code. You're attempting to allocate a bunch of character arrays together into a buffer than is only 5 bytes long:

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);

This is likely overwriting your local variable hSocket , resulting in the "bad file descriptor error".

Since you're using C++ (you have a vector in your code), just use a std::string instead of C arrays of characters so that you don't have to worry about memory management.

Another cause of 'Bad file descriptor' can be encountered when trying to write into a location onto which you do not have write permission . For example, when trying to download content with wget in Windows environment:
Cannot write to 'ftp.org.com/parent/child/index.html' (Bad file descriptor).

Another cause of 'bad file descriptor' can be accidentally trying to write() to a read-only descriptor. I was stuck on that for a while because I was spending all my time looking for a second close() or buffer overrun.

Another case may be the target out file name includes characters the filesystem won't allow. For instance, suppose you are running wget command on a Linux computer and the target path is an external hard drive formatted with NTFS. The Linux Ext4 filesystem will allow for characters such as '?', but the NTFS filesystem will not. The default behavior for wget is to name the target folder as the specified url. If the url contains a special character like ':', NTFS will not accept that character, resulting in the error "Bad file descriptor". You can disable this default behavior in wget with the --no-host-directories parameter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM