2
votes

When attempting to create a simple UDP client, my code successfully opens the socket and reads in a small buffer from a file to be sent to a server specified by host address and port number by command line arguments.

However, the sendto and recvfrom both fail with "Bad File Descriptor" and I can't figure out why.

void main(int argc, char* argv[]){
int s, n=0, obytes, inbytes;
struct sockaddr_in sin;
char *buffer;
int address = 0;

//Checks socket
if((s = socket(AF_INET, SOCK_DGRAM, 0))<0) {
    printf("Error creating socket\n");
    exit(0);
}
//Resets values in socket structure
memset((char*)&sin, 0, sizeof(sin));
sin.sin_port = htons(atoi(argv[2]));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(argv[1]);
printf("%d\n", sin.sin_addr.s_addr);
/*Opens file to be sent and reads into buffer*/
FILE *readFile;
readFile = fopen(argv[3], "r");
//Checks if file to be read can be opened
if (readFile==NULL) {
    perror ("Error opening file");
}
//Reads in all the characters to a buffer
else{
    while (!feof(readFile)) {
        buffer[n] = fgetc (readFile);
        n++;
    }

buffer[n] = '\0';
printf ("Total number of bytes: %d\n", n);
for(int i = 0; i< n; i++){
    printf("%c", buffer[i]);
}
}
printf("File was opened\n");
//Sends the buffer to the destination designated by the socket structure and checks to see if bytes were sent
if((obytes = sendto(s, buffer, strlen(buffer), 0, (struct sockaddr *)&sin, sizeof(sin))) == -1 ) {
    perror("Sendto() error!");
    exit(1);
}
printf("%d bytes were sent\n",obytes);
//Receives response from the server and checks to see if bytes were actually received
/*  if((inbytes = recvfrom(s, buffer, strlen(buffer)+28, 0, (struct sockaddr *)&sin, sizeof(struct sockaddr*))) == -1 ) {
    perror("Recvfrom() error!");
    exit(1);
}*/
printf("%d bytes were received.\n", inbytes);
//Closes file
fclose (readFile);

}
2
Put the output of your code, the printf I mean.Eric Fortin
It's amazing this program gets to sendto because it's writing a bunch of data to the uninitialized pointer buffer. To see if this is causing your socket stuff to fail, change your declaration to char buffer[1000] or whatever and see if it works. In real life, you'd probably want to use some kind of dynamic allocation though. The socket code looks okay, though sendto() will fail if you try to send too much data on a dgram socket.Splat

2 Answers

4
votes

I see a few errors/problems:

  • You never seem to set n to be the length of the file
  • There is no memory allocation to hold the file
  • Reading a file one byte at a time will be very inefficent
  • After loading the file you should know the length of the file, no need to use strlen()
  • If the file is binary, strlen() will fail since it will stop at the first embedded byte with the value 0
1
votes

Without the output, it's kind of hard but first thing I noticed was that you never allocated buffer to write the file in.