Hello,

I've written a short app that (in theory) connects to a remote box on port 23, and simply reads what is returned. The ultimate goal is to log on to the box automatically in order to automate some of my less interesting tasks. I get the socket set up, and it connects without error, but when I read out what should be the version banner and prompt text from the server and display it, it's all complete gibberish:

ÿ_%ÿy↑  èI" Em  at  ÿÿÿÿ<"►a'O?|IkYwH  àÉ" èE" ♀   ìE"     ☺ ♦              É" ☻
 X ♥     $    ►☺♣     ♣§   (P§VÑ6D]<-à$⌂e☺   ↑    ►☺☻     ♣     ☻    ¶    ►☺☺  ♣
↕        dÉ"         ☻   2"◄a0E" ,É" W_a0E" 2"◄a♥☺  'O?|IkYwL  àÉ" "É" tlYw¬♦  O
E" 8§`|-§`|ë♠`| ►¶a↑♦  ☺   àÉ" 0E" ♥☺  2"◄adÉ" 0E" ♥☺
a.exe              @E"   $ 2`|♥   ↑$   $  E$ ↑E"     \I" ↑î?|8`|ÿÿÿÿ2`|«♠`|ë♠`|x
S▬a 6^|☺       U-
a            x☺5                                      
5                                           x☺5     ^♠5         ä+YwªE" x☺5 ∟  "

5 O>`| 
5 ►E" F `|X☺fA▬a
   (E" å9☺A▬a1g↕a

I initialized the buffer to null, and confirmed that with output, so that really is what read() is kicking back to me, and not just the remnants of whatever memory was grabbed to allocate the buffer. Any ideas?

Please excuse the mess, I've been screwing with it for a while now.

#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>

using namespace std;

#define PORT 23
#define EXIT_FAILURE -1
#define EXIT_SUCCESS 0



int main(int argc, char *argv[])
{
  char *arg_host = "testbox";  // temp statically filled

  int sock;
  struct sockaddr_in srvname;
  struct hostent *srvinfo;

  char buf[BUFSIZ];
  char sendbuf[BUFSIZ];

  sprintf(buf, "\0");

  sock = socket(PF_INET, SOCK_STREAM, 0);
  if (sock < 0)
  {
    perror("socket creation");
    return(EXIT_FAILURE);
  }

  srvname.sin_family = AF_INET;
  srvname.sin_port = htons(PORT);
  srvinfo = gethostbyname(arg_host);

  if (srvinfo == NULL)
  {
    perror("gethostbyname() failed");
    printf("failure: gethostbyname( %s )\n", arg_host);
  }

  srvname.sin_addr = *(struct in_addr *) srvinfo->h_addr;

  if (connect(sock, (struct sockaddr*) &srvname, sizeof(srvname)) < 0)
  {
    perror("connect process");
    return(EXIT_FAILURE);
  }

  sleep(1);
  // we'll grab welcome text as a test
  read(sock, buf, sizeof(buf));
  printf("Buffer: %s\n", buf);

  int numdisp = 0;
  for (int i = 0 ; i < sizeof(buf) ; i++)
  {
    if (numdisp++ % 10 == 0) printf("\n");
    printf("%i\t", buf[i]);
  }
  printf("\n\nTranslation:\n");

  for (int i = 0 ; i < sizeof(buf) ; i++)
  {
    printf("%c", buf[i]);
  }

  sprintf(sendbuf, "testing");
  write(sock, sendbuf, sizeof(sendbuf));
  sleep(1);
  read(sock, buf, sizeof(buf));
  printf("\n\n%s", buf);

  close(sock);
  // if all goes well...
  return(EXIT_SUCCESS);
}
Comments
Well done on using code tags and nicely formatted code. So few newbies achieve so much on their first code post.

> sprintf(buf, "\0");
Whilst not harmful, it's probably not as useful as you think.

> read(sock, buf, sizeof(buf));
Read returns a result (the number of chars, or an error). Use it.
As in

int n = read(sock, buf, sizeof(buf)-1 );
if ( n > 0 ) {
  buf[n] = '\0';
  printf( "%s\n", buf );
} else if ( n == 0 ) {
  // connection closed
} else if ( n < 0 ) {
  // error
}

The -1 is necessary to allow room for the \0 to be appended. Low level read/write calls don't append anything.

> for (int i = 0 ; i < sizeof(buf) ; i++)
Again, use the result of the read call to determine how much data you really have.
Just because you asked for sizeof(buf) doesn't mean you got that much.

> sprintf(sendbuf, "testing");
Try sending a properly formatted telnet command.

> write(sock, sendbuf, sizeof(sendbuf));
1. Use the return result to determine success (or otherwise)
2. Use strlen(sendbuf) to send just the data. Not the data and hundreds of bytes of garbage.

All of your corrections are duly noted, but why is it that the initial string of data sent by the server is complete gibberish? I'm essentially stuck at that end, due to my inability to glean any useful information from what is returned from server itself.

Thanks much! I'll try that out when I get a moment. And with those other suggested changes, everything seems to be working more smoothly than before.

This article has been dead for over six months. Start a new discussion instead.