I'm trying to send a string to a server application using C, but I've hit a snag. I'm fairly new to network programming, and I think my code is barking up the wrong tree.
The message is supposed to be message length + message and is unpacked on the other side by a python server as such (buf being the raw incoming data):
msg_len_bytes = buf[0:4]
msg_len = struct.unpack("!L", msg_len_bytes)[0]
! means network byte order and L means unsigned long.
It is fairly simple to send a regular string. send(sock, message, strlen(message), 0);
But adding the message length I can't quite get a handle on. Here is the code for my client thus far:
struct msgstruct {
uint32_t length;
char send_data[4096];
};
int main()
{
int sock;
struct msgstruct message;
char data[4096] = "<MOP><test/></MOP>";
for ( int i = 0; i < strlen(data); i++ ) {
message.send_data[i] = data[1];
}
struct hostent *host;
struct sockaddr_in server_addr;
unsigned long buflen = sizeof(message.send_data);
uint32_t bufsend = htonl(buflen);
message.length = bufsend;
host = gethostbyname("127.0.0.1");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(12998);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(server_addr.sin_zero),8);
if (connect(sock, (struct sockaddr *)&server_addr,
sizeof(struct sockaddr)) == -1) {
perror("Connect");
exit(1);
}
if(send(sock, message.length + message.send_data, sizeof(message), 0) == -1){
printf("\nSocket error.");
exit(1);
}
return 0;
}
I've tried a few variations, but I always end up with a socket error. Is it because I'm mixing types in the second arguement for send? I get compilation errors if I try to send the struct.
You can use 2 subsequent sends:
send(sock, &message.length, sizeof(message.length), 0);
send(sock, message.send_data, message.length*sizeof(char), 0);
Or better prepare buffer with first 4 bytes as message length:
char buff[MAX_BUFF] = "";
int len_disp = sizeof(message.length);
memcpy(buff, &message.length, len_disp);
memcpy(&buff[len_disp], &message.length, message.length*sizeof(char));
send(sock, buff, message.length*sizeof(char) + len_disp, 0);
EDIT: For small messages comment -- disabling Nagle's algorithm.
BOOL bNagleEnabled = FALSE;
if(setsockopt(sAccept, IPPROTO_TCP, TCP_NODELAY, (char *)&bNagleEnabled, sizeof(BOOL)))
{
ReportError("Setting TCP_NODELAY socket option failed");
return -2;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With