1

I have a basic TCP client/server program.

I have a method in both the client and the server that reads and writes. It works perfectly the first time I run it, but when it runs again (it's in a loop) it doesn't read anything in.

void printout(int newsockfd, char buffer) {
n = write(newsockfd, a2, 256);
n = write(newsockfd, a3, 256);
n = write(newsockfd, a4, 256);
n = write(newsockfd, a5, 256);
n = write(newsockfd, a6, 256);
}

in the server

void printout(char buffer[], int sockfd) {
bzero(buffer, 256);
n = read(sockfd, buffer, 256);
printf("%s\n", buffer);
n = read(sockfd, buffer, 256);
printf("%s\n", buffer);
n = read(sockfd, buffer, 256);
printf("%s\n", buffer);
n = read(sockfd, buffer, 256);
printf("%s\n", buffer);
n = read(sockfd, buffer, 256);
printf("%s\n", buffer);
}

a2, a3, a4, a5, and a6 are strings. The first time it runs it prints everything properly. The second time, it prints out nothing, just a bunch of blank lines. When I tested to find out what buffer was, I got that its " ". Do you know what the problem is or how I can fix it?

B M
  • 11
  • 2
  • Try printing out the value of `n` after each `write` call, and the value of `n` after each call to `read`. If `n` is every less than zero, print the value of `errno`. – Robᵩ Jan 25 '12 at 18:07
  • Your code ignores the return value from `read`, so it has no idea how many bytes it received. You also can't treat arbitrary bytes received over the network as a C-style string. – David Schwartz Jan 25 '12 at 19:18
  • It says n is 256 after every call... – B M Jan 25 '12 at 23:40

2 Answers2

3

It's hard to pinpoint the problem since you're not showing us the loop.

However, one thing that jumps out is that you seem to be expecting that every call to write() would match up with a call to read(). This is not how TCP works: packets get fragments, you could get partial reads etc. In other words, TCP is a stream protocol and not a message-oriented one.

In particular, you should be prepared to deal with the situation whereby read() returns fewer than 256 bytes. That can happen to any of your read() calls at any time.

Also, since you're treating the 256-byte chunks as C strings, it would be prudent for the server to append its own NUL terminator instead of relying on the client to supply one.

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • The code is over 400 lines long. Basically the while loop is while(l > 0) { printout(); a bunch of other stuff} in both the client and the server. l is decreased every turn. How do I get read/write to match up? – B M Jan 25 '12 at 16:39
  • 2
    Since read and write aren't guaranteed to read/write the specified number of bytes, I would recommend writing wrappers for read and write that keep calling them until the specified number of bytes have been read/written. There are other approaches, but without seeing the rest of your code, it's hard to recommend other approaches. – Klox Jan 25 '12 at 16:45
0

'll bet your server's call to bind() failed on the second run. And so the client's call to connect(). Got error handling for those?

EDIT

Especially when doing simple TCP examples, it's not uncommon for the first run of your server to "hold on" to a port for a while after the server dies. When you run the server a second time, bind() will fail, and so your server process won't be able to listen() or accept() new connections. Explaining the details is the topic of another question.

Since your server isn't actually there, connect() will fail on your client, leaving you with an unconnected socket. And all subsequent reads from that socket will fail immediately, leaving buffer containing all 0s. This would be a possible explanation of the behavior you're seeing.

Can you rule this explanation out? Are you checking that bind() and connect() always return 0?

Managu
  • 8,849
  • 2
  • 30
  • 36