Uğur Cibaroğlu Uğur Cibaroğlu - 8 months ago 57
C Question

TCP client in Java and server in C

I would like to make a chat application. The client will be written with java and the server will be written with C. On the server side, the message will be sent as struct. On the client side, how do I read and separate the message with Java?

Here is a sample packet structure:

struct s_packet{
int text_color;
char text[TEXTSIZE];
char alias[ALIASIZE];

Here is a sample server(in C) send function:

send(iter->client.sockfd, (void *)se_packet, sizeof(s_packet), 0);

Here is a sample client recv function in C:

recv(m_sockfd, (void *)&se_packet, sizeof(s_packet),0);

printf("\x1b[3%dm <%s>: %s \x1b[0m\n", se_packet.text_color, se_packet.alias, se_packet.text);

I can read s_packet and separate in C, but How can I do it in java?

How can i separate like that in Java:

printf("\x1b[3%dm <%s>: %s \x1b[0m\n", se_packet.text_color, se_packet.alias, se_packet.text);

Answer Source

The definite answer is that it won't be so easy. The first thing you should understand is how tcp works. It's a stream oriented protocol and there's no such thing as a "message" in tcp. You just send and receive a stream of bytes.

In your snippet of code recv can finish after reading a part of message sent from the server. Instead you should keep a local buffer in java and drop all the data you've received so far. In a while loop you can detect if a message that is ready for processing was received. If your message is not very big (less than the MTU), then you may get lucky and always receive the whole 'message'. If you are not concerned with that then you may just use java.io.InputStream.read(byte[]) method.

The other thing to consider is how you interpret a message you received. Well you have no other choise but to process it as byte[] in Java. First you may want to read s_packet.text_color. It probably will be placed as first 4 bytes in a message. You can construct int from thoes bytes (see Convert 4 bytes to int for example). But this is not a good practice. This is because you send a binary data that is depends on how your s_packet is represented in memory. In real life you usually don't know what will be the size of int or char, it's platform dependent. Or sometimes the order of bytes inside int itself can differ. Instead you should declare your own serialization protocol and how your message is converted to binary data and vice versa. Hope it helps.