Good evening all. I am working on a poker program, using a TCP client/server. I am having the client do only input/output work, while the server handles all of the operations.
I have run into a problem where I have a card structure that is populated with 5 cards from a deck. I put those 5 cards into 2 arrays, one for the face of the card, the other for the suit. I am them trying to send these arrays to the client to print the hand out for the user. The array gets filled with no problem, but when I send the array to the client, and print it, it prints nothing. There is a lot of code, most of which is messy, so for the time being I will post the code in question, unless you guys need more.

It works for the first buffer read. For example if the first face that the server sends in 4, the print loops in the client will only print
4 of
4 of
4 of
4 of
4 of
Can the buffer not be overwritten? - drewd12 3 hrs ago

However handFace[] is an array of pointers so as you go through this loop you set handFace[v] to point to buffer1, i.e. the item contains the address of buffer1. So at the end of each loop every element of handFace will point to the same item, which is whatever is in buffer1 at that time. The same holds true for handSuit and buffer2. What your code needs to do is allocate a buffer to each element of the array to hold the item that has just been read in and copy it to the new buffer, something like:

Unfortunately this logic is still flawed, as you cannot be certain of what has been received in either buffer1 or buffer2. What you read from a socket is whatever is pending from your server, which could be any number of cards and suits, or none. So as you read the data from the socket you will need to disassemble it into its constituent parts before storing it in your arrays. The best way to achieve this is to design some message structure that your client and server use for communication, which allows each to identify each card, its value and suit. So perhaps your messages could appear in the form of:

#Five;Hearts#King;Clubs##

Where the '#' identifies the next card with the value and suit seperated by the ';' character. The double '#' character signifies the end of the data.

Solution 4

Quote: I replaced sizeof() with strlen() in both the read and write statements, and removed the &, but that gives me a seg fault. Any ideas?

You cannot use uninitialised pointers as destinations for your read statements. You must read into a buffer that is at least long enough to hold whatever message you receive on the socket. Something like:

char buffer[255];
n = read(sockfd, buffer, sizeof(buffer));

Then transfer the input field to its proper location and save a pointer to it in your array.

Using pure C for a program like this is probably not a great idea. If you convert to C++ you will be able to take advantage of the extra features of the Standard Template Library for managing strings, arrays and such like.

Solution 5

OK, I have updated your original question with the latest code you posted. However you still seem to be having a problem with the difference between sizeof() and strlen(). sizeof() is a compile time directive that returns the size of an element or array as declared at compile time; strlen() is a runtime function that returns the actual size of a null terminated string, regardless of the size of the buffer it is contained within. Thus your write statements should be of the form:

n = write(newsockfd, handFace[y], strlen(handFace[y]));

Note the correct use of strlen() to write the actual length of the string rather than sizeof() which returns the length of a pointer.

I also think that the first loop that copies the pointers from myDeck.myCards to handFace as in

handFace[v] = myDeck.myCards[v].face;

is a waste of time; why not write to the socket direct from myDeck.myCards[v].face?

In your read code you read successive items into buffer1 and buffer2 but then point all the items at the same buffer thus losing the first four items you read in. After reading each item you need to copy it to a permanent location before setting the handFace[] or handSuit[] elements to point to it.

Further comments:
You seem to be misunderstanding some of the basics of pointers and arrays and copying items between them; I would suggest going over the relevant section of your C language reference.

You also do not check the result of any of your socket IO calls to see what you are actually writing or reading (how big are your buffers?). Never assume that all function calls are successful, or that they give the results that you expect.

One way of learning exactly what is going on in your program is to use the debugger and step through your code and look at the contents of your variables and arrays to see the results of each step.

Let me first thank you for everything you have done so far. Your help has been invaluable. I think I am understand the concepts of strlen() vs sizeof(). What I don't quite understand is what you mean when you said I am pointing all items at the same buffer and losing the first four items. The way I have it written, I would think it would read the first face and the first suit into buffer1 and buffer2 respectively, then stick them in the handFace[0] and handSuit[0] so I could access them, and continue to do this for each increment in the loop. Where do I fail this logic?