I am currently working on sending and receiving a message via UDP client-server relationship, where a raspberry pi is the client sending a message to a PC. I've been trying to translate the following python code for this (which works) into C, but it's unclear where the error in my code is. As you can see, the C output only has the first few elements of the message, and doesn't accurately show the message that is being sent. Thanks! The working Python code:
import socket
UDP_IP = "169.254.0.1"
UDP_PORT = 36112
#RBP Commands
#MESSAGE = '01 01 4c 30 73 01'; #Set for remote mode
#MESSAGE = '01 01 4c 30 73 00'; #Clear remote mode
#MESSAGE = '01 00 4C 31' #Get module info
MESSAGE = '01 01 4C 53 73 00 43 00 00 01 2c 00 00 00 00 00 00 00 00' #Send Setpoint
#MESSAGE = '01 01 4C 52 18' #Set run state to run
#MESSAGE = '01 01 4C 52 02' #Set run state to stop
print("UDP target IP:", UDP_IP)
print("UDP target port:", UDP_PORT)
print("message:", MESSAGE)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
sock.sendto(bytes.fromhex(MESSAGE), (UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(255)
print("received message:", data.hex())
exit();
output: outputs the message that was sent C code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdint.h>
#include <unistd.h>
int main(void){
int socket_desc;
struct sockaddr_in server_addr;
char server_message[60];
uint8_t client_message[]= {0x01, 0x01, 0x4C, 0x53, 0x73, 0x00, 0x43, 0x00, 0x00, 0x01, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // send setpoint
int server_struct_length = sizeof(server_addr);
// Clean buffers:
memset(server_message, '\0', sizeof(server_message));
//memset(client_message, '\0', sizeof(client_message));
// Create socket:
socket_desc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(socket_desc < 0){
printf("Error while creating socket\n");
return -1;
}
printf("Socket created successfully\n");
// Set port and IP:
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(36112);
server_addr.sin_addr.s_addr = inet_addr("169.254.0.1");
printf("Sending message:");// changed all the variables in for loops to be local to those loops ***********************
printf("\n");
for(uint16_t i=0; i<sizeof(client_message); i++){
if(i%15 == 0){
printf("\n");
printf("0x%X\t", client_message[i]);
}
}
// Send the message to server:
if(sendto(socket_desc, client_message, strlen(client_message), 0, (struct sockaddr*)&server_addr, server_struct_length) < 0){
printf("Unable to send message\n");
return -1;
}
// Receive the server's response:
if(recvfrom(socket_desc, server_message, sizeof(server_message), 0, (struct sockaddr*)&server_addr, &server_struct_length) < 0){
printf("Error while receiving server's msg\n");
return -1;
}
printf("\nReceived message:");
for(uint16_t i=0; i<sizeof(server_message); i++){
if(i%15 == 0)
printf("\n");
printf("0x%X\t", server_message[i]);
}
printf("\n");
// Close the socket:
close(socket_desc);
return 0;
}
if(sendto(socket_desc, client_message, strlen(client_message), 0, ... ^^^^^^^
You only send strlen(client_message)
data, which is not the full size of the client message. A string in C is terminated by \0
, so the length of the string is determined on the position of the first \0
. Only, your message contains several \0
inside, so it is not actually a string and string functions should not be used on it. Use sizeof(client_message)
instead.