I am not sure whether I need to use any synchronisation in the thread functions(sendMsg() and receiveMsg()) in the following program. I'm using a single global UDP socket in the program which is being used in these functions which will be used in multiple threads.
Please also note that the IP and port for receiving and sending the messages are constant.
#include <string.h>
#include <unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
const char* g_upfIp;
unsigned short g_upfPort;
const char* g_smfIp;
unsigned short g_smfPort;
sa_family_t g_ipType;
void initialiseSocket();
int sendMsg(char* pkbuf, size_t len);
int receiveMsg(char* payload, size_t payloadLength);
void udpServer();
int main(int argc, char** argv)
{
//Initialise IP and port
...
initialiseSocket();
// Now I'll be using multiple threads for udpServer() and sendMsg();
}
void initialiseSocket() {
if(g_ipType == AF_INET6) {
g_socket = socket(PF_INET6, SOCK_DGRAM, 0);
if (g_socket < 0) {
perror("creating socket");
exit(1);
}
addr6.sin6_family = g_ipType;
inet_pton(g_ipType, g_smfIp, &addr6.sin6_addr);
addr6.sin6_port = htons(g_smfPort);
bind(g_socket, (sockaddr*)&addr6, sizeof(addr6));
}
else {
g_socket = socket(PF_INET, SOCK_DGRAM, 0);
if (g_socket < 0) {
perror("creating socket");
exit(1);
}
addr4.sin_family = g_ipType;
inet_pton(g_ipType, g_smfIp, &addr4.sin_addr);
addr4.sin_port = htons(g_smfPort);
bind(g_socket, (sockaddr*)&addr4, sizeof(addr4));
}
}
int sendMsg(char* pkbuf, size_t len)
{
printf("\n[%s::%d]Inside sendMsg dest IP[%s], dest port[%d], srcIP[%s]\n",__FILE__,__LINE__,g_upfIp,g_upfPort,g_smfIp);
size_t size;
struct sockaddr_in6 serverAddr6;
struct sockaddr_in serverAddr4;
if(g_ipType == AF_INET6) {
memset(&serverAddr6, 0, sizeof(serverAddr6));
serverAddr6.sin6_family = g_ipType;
inet_pton(g_ipType, g_upfIp, &serverAddr6.sin6_addr);
serverAddr6.sin6_port = htons(g_upfPort);
size = sendto(g_socket, pkbuf, len, 0 , (const struct sockaddr *) &serverAddr6,sizeof(serverAddr6));
if(size < 0) {
printf("Error in sending message\n");
return -1;
}
}
else {
memset(&serverAddr4, 0, sizeof(serverAddr4));
serverAddr4.sin_family = g_ipType;
inet_pton(g_ipType, g_upfIp, &serverAddr4.sin_addr);
serverAddr4.sin_port = htons(g_upfPort);
size = sendto(g_socket, pkbuf, len, 0 , (const struct sockaddr *) &serverAddr4,sizeof(serverAddr4));
if(size < 0) {
printf("Error in sending message\n");
return -1;
}
}
printf("[%d] bytes written to %s:%d\n",size, g_upfIp, g_upfPort);
return 0;
}
int receiveMsg(char* payload, size_t payloadLength) {
printf("\nInside receiveMsg IP[%s], port[%d]\n",g_smfIp,g_smfPort);
int size;
char srcIp[1000] = {0};
unsigned short srcPort;
if(g_ipType == AF_INET6) {
sockaddr_in6 addr = {0};
socklen_t addrlen;
addrlen = sizeof(addr);
size = recvfrom(g_socket, payload, payloadLength, MSG_TRUNC , (struct sockaddr *) &addr,&addrlen);
}
else {
sockaddr_in addr = {0};
socklen_t addrlen;
addrlen = sizeof(addr);
size = recvfrom(g_socket, payload, payloadLength, MSG_TRUNC , (struct sockaddr *) &addr,&addrlen);
}
printf("\n[%d] bytes received from %s:%d\n",size,g_upfIp,g_upfPort);
return size;
}
void udpServer() {
printf("\n[%s::%d]Inside udpServer\n",__FILE__,__LINE__);
int size;
//In a while loop, receive incoming message in a buffer.
while(true) {
char buffer[1024]={0};
size = receiveMsg(buffer,1024);
printf("\nMsg Received --> %s\n",buffer);
}
}