How to send data using internet on C language windows - c

I am pretty new to socket programming and the C language. I want to teleoperate a robot over the internet for that I have to send some values to a robot computer. Here is my code...
x = state.position_val[0];
y = state.position_val[1];
z = state.position_val[2];
Rx = state.gimbal_joints[0]*1000;
Ry= state.gimbal_joints[1]*1000;
Rz = state.gimbal_joints[2]*1000;
double arr[7] = { x, y, z, Rx, Ry, Rz, btonn };
SAFEARRAY* psa = SafeArrayCreateVector(VT_R8, 0, 7);
void* data;
SafeArrayAccessData(psa, &data);
CopyMemory(data, arr, sizeof(arr));
SafeArrayUnaccessData(psa);
return psa;
These are the code snippets under the while loop at each loop this code gets the state value of the robot and creates an array that is further used for teleoperation. I need to send this array over the internet to another computer.
Please help me how to do this?

I have tested this on Windows machine
Go to https://ngrok.com create an account
your robot should run ngrok client use following commands
ngrok authtoken xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ngrok tcp 80
Forwarding tcp://3.tcp.ngrok.io:15842 -> localhost:80
Here ngrok will assign a local PORT to 80 and random port to outside network ie Interner exposed port. You have to add 80 and that port to your firewall rules of robot network device).
Goto https://whatismyipaddress.com/hostname-ip here put 3.tcp.ngrok.io Look IP address box from ngrok console out. You will get your robot's global IP. that you can connect to your robot from anywhere in the world.
Following are the Client and Server examples that you can compile and run.
gcc .\Client.c -o Client
gcc .\Server.c -o Server
Client.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
//Create a Socket for server communication
short SocketCreate(void)
{
short hSocket;
printf("Create the socket\n");
hSocket = socket(AF_INET, SOCK_STREAM, 0);
return hSocket;
}
//try to connect with server
int SocketConnect(int hSocket)
{
int iRetval=-1;
int ServerPort = 15842; // ngroks external tcp port
struct sockaddr_in remote= {0};
remote.sin_addr.s_addr = inet_addr("3.134.xxx.xxx"); //Robot IP
remote.sin_family = AF_INET;
remote.sin_port = htons(ServerPort);
iRetval = connect(hSocket,(struct sockaddr *)&remote,sizeof(struct sockaddr_in));
return iRetval;
}
// Send the data to the server and set the timeout of 20 seconds
int SocketSend(int hSocket,char* Rqst,short lenRqst)
{
int shortRetval = -1;
struct timeval tv;
tv.tv_sec = 20; /* 20 Secs Timeout */
tv.tv_usec = 0;
if(setsockopt(hSocket,SOL_SOCKET,SO_SNDTIMEO,(char *)&tv,sizeof(tv)) < 0)
{
printf("Time Out\n");
return -1;
}
shortRetval = send(hSocket, Rqst, lenRqst, 0);
return shortRetval;
}
//receive the data from the server
int SocketReceive(int hSocket,char* Rsp,short RvcSize)
{
int shortRetval = -1;
struct timeval tv;
tv.tv_sec = 20; /* 20 Secs Timeout */
tv.tv_usec = 0;
if(setsockopt(hSocket, SOL_SOCKET, SO_RCVTIMEO,(char *)&tv,sizeof(tv)) < 0)
{
printf("Time Out\n");
return -1;
}
shortRetval = recv(hSocket, Rsp, RvcSize, 0);
printf("Response %s\n",Rsp);
return shortRetval;
}
//main driver program
int main(int argc, char *argv[])
{
int hSocket, read_size;
struct sockaddr_in server;
char SendToServer[100] = {0};
char server_reply[200] = {0};
//Create socket
hSocket = SocketCreate();
if(hSocket == -1)
{
printf("Could not create socket\n");
return 1;
}
printf("Socket is created\n");
//Connect to remote server
if (SocketConnect(hSocket) < 0)
{
perror("connect failed.\n");
return 1;
}
printf("Sucessfully conected with server\n");
printf("Enter the Message: ");
gets(SendToServer);
//Send data to the server
SocketSend(hSocket, SendToServer, strlen(SendToServer));
//Received the data from the server
read_size = SocketReceive(hSocket, server_reply, 200);
printf("Server Response : %s\n\n",server_reply);
close(hSocket);
shutdown(hSocket,0);
shutdown(hSocket,1);
shutdown(hSocket,2);
return 0;
}
Server.c
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
short SocketCreate(void)
{
short hSocket;
printf("Create the socket\n");
hSocket = socket(AF_INET, SOCK_STREAM, 0);
return hSocket;
}
int BindCreatedSocket(int hSocket)
{
int iRetval=-1;
int ClientPort = 80; //Robot local port
struct sockaddr_in remote= {0};
/* Internet address family */
remote.sin_family = AF_INET;
/* Any incoming interface */
remote.sin_addr.s_addr = htonl(INADDR_ANY);
remote.sin_port = htons(ClientPort); /* Local port */
iRetval = bind(hSocket,(struct sockaddr *)&remote,sizeof(remote));
return iRetval;
}
int main(int argc, char *argv[])
{
int socket_desc, sock, clientLen, read_size;
struct sockaddr_in server, client;
char client_message[200]= {0};
char message[100] = {0};
const char *pMessage = "hello aticleworld.com";
//Create socket
socket_desc = SocketCreate();
if (socket_desc == -1)
{
printf("Could not create socket");
return 1;
}
printf("Socket created\n");
//Bind
if( BindCreatedSocket(socket_desc) < 0)
{
//print the error message
perror("bind failed.");
return 1;
}
printf("bind done\n");
//Listen
listen(socket_desc, 3);
//Accept and incoming connection
while(1)
{
printf("Waiting for incoming connections...\n");
clientLen = sizeof(struct sockaddr_in);
//accept connection from an incoming client
sock = accept(socket_desc,(struct sockaddr *)&client,(socklen_t*)&clientLen);
if (sock < 0)
{
perror("accept failed");
return 1;
}
printf("Connection accepted\n");
memset(client_message, '\0', sizeof client_message);
memset(message, '\0', sizeof message);
//Receive a reply from the client
if( recv(sock, client_message, 200, 0) < 0)
{
printf("recv failed");
break;
}
printf("Client reply : %s\n",client_message);
if(strcmp(pMessage,client_message)==0)
{
strcpy(message,"Hi there !");
}
else
{
strcpy(message,"Invalid Message !");
}
// Send some data
if( send(sock, message, strlen(message), 0) < 0)
{
printf("Send failed");
return 1;
}
close(sock);
sleep(1);
}
return 0;
}
You can now send receive data between robot and your computer

Related

Couldn't receive message from a TCP client in C

I'm trying to create a server that can receive messages from multiple connected clients, but in my code, the recv() function always return -1. How can I make my server receive codes from the client?
This is my server. The recv() function is called in the while loop at the bottom.
I tried to use read(), but I couldn't find a way to make it unblocking. Is there any way to interpret this by using read()? If not, How can I fix this problem with recv() always returning -1, despite I have a new client connected and have a new message sent?
/*------------------Header Files----------------------------------------------------------------------*/
#define _GNU_SOURCE
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<sys/stat.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<arpa/inet.h>
/*-------------------Linked List------------------------------------------------------------------------*/
struct client_online{
int client_socket;
char* name;
struct client_online* next;
};
/*-------------------Global Variables-------------------------------------------------------------------*/
struct client_online* first_client = NULL;
/*-------------------Main Function----------------------------------------------------------------------*/
int main(int argc, char* argv[]){
// Cite: get help from office hour code
// Creating the socket
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
if(server_socket < 0){
perror("Error creating server socket");
return -1;
}
// Server address
struct sockaddr_in server_address;
memset(&server_address, 0, sizeof(struct sockaddr_in));
server_address.sin_family = AF_INET;
server_address.sin_port = htons(atoi(argv[2]));
server_address.sin_addr.s_addr = inet_addr(argv[1]);
// Binding the socket
int binder = bind(server_socket, (const struct sockaddr *) &server_address, sizeof(server_address));
if(binder == -1){
perror("Error calling bind");
return -1;
}
// Listen to the socket
int listener = listen(server_socket, 50);
if(listener == -1){
perror("Error calling listen");
return -1;
}
// Client address
struct sockaddr_in client_address;
// Reading and writing
int quit = 0;
while(!quit){
// Check if there is a new connection
int client_address_size = sizeof(client_address);
int each_client_socket = accept4(server_socket,
(struct sockaddr*) &client_address,
&client_address_size,
SOCK_NONBLOCK);
// If there is a new connection, add client to linked list
if(each_client_socket >= 0){
if(first_client == NULL){
first_client = malloc(sizeof(*first_client));
first_client->client_socket = each_client_socket;
first_client->name = (char*)malloc(100);
strcpy(first_client->name,"User");
first_client->next = NULL;
free(first_client->name);
free(first_client);
}
else{
struct client_online* tracker = first_client;
while(tracker->next != NULL){
tracker = tracker->next;
}
struct client_online* new_client;
new_client = malloc(sizeof(*new_client));
new_client->client_socket = each_client_socket;
new_client->name = (char*)malloc(100);
strcpy(new_client->name, "User");
new_client->next = NULL;
tracker->next = new_client;
free(new_client->name);
free(new_client);
}
}
// Check if there are messages recieved
struct client_online* checker = first_client;
while(checker != NULL){
char client_response[256];
char toSend[256];
bzero(client_response, sizeof(client_response));
int receiver = recv(checker->client_socket,
client_response,
sizeof(client_response),
MSG_DONTWAIT);
printf("%d\n", receiver);
if(receiver > 0){
printf("message received\n");
snprintf(toSend, sizeof(toSend), "%s: %s\n", checker->name, client_response);
struct client_online* sender = first_client;
while(sender != NULL){
send(sender->client_socket, toSend, sizeof(toSend), MSG_DONTWAIT);
}
}
checker = checker->next;
}
sleep(1);
}
return 0;
}
Here is my client
/*----------------------------------------------------Header Files----------------------------------------*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<sys/stat.h>
#include<netinet/ip.h>
#include<arpa/inet.h>
#define _GNU_SOURCE
/*----------------------------------------------------Main Function--------------------------------------*/
int main(int argc, char* argv[]){
// Seek help from office hour codes
// Create the client socket
int client_socket = socket(AF_INET, SOCK_STREAM, 0);
if(client_socket < 0){
perror("Error creating client socket");
return -1;
}
// Construct the address of the connection
struct sockaddr_in client_address;
memset(&client_address, 0, sizeof(struct sockaddr_in));
client_address.sin_family = AF_INET;
client_address.sin_port = htons(atoi(argv[2]));
client_address.sin_addr.s_addr = inet_addr(argv[1]);
// Connect the client to the server
int connecter = connect(client_socket,
(const struct sockaddr*) &client_address,
sizeof(struct sockaddr_in));
if(connecter < 0){
perror("Error connecting to server");
}
// Reading and writing
int quit = 0;
while(!quit){
// Read from command line
char client_message[256];
memset(&client_message, 0, sizeof(client_message));
int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
int reader = read(STDIN_FILENO, client_message, sizeof(client_message));
if (reader > 0) {
// Writing normal message
send(client_socket, client_message, 1, MSG_WAITALL);
}
//
sleep(1);
}
return 0;
}
Since you are passing MSG_DONTWAIT to your recv call, if there is nothing to receive from the client yet, the call will return an error to indicate that fact.
If you are using polling mechanism, like epoll, then you would typically wait for a readable notification. Once the notification is received, you can retry the recv call. I don't see any use of a polling mechanism in your code.
Alternatively, you can spawn a thread for each new connection, and use blocking calls to recv (omit the MSG_DONTWAIT flag).

Multiple Client single server using select

he server is accepting the clients, but no message is received. Here is my code for server:
Server:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>
#include<stdbool.h>
#include<sys/select.h>
#include<errno.h>
//Socket Creation
int socketFile(){
int Socket = socket(AF_INET, SOCK_STREAM, 0);
if(Socket == -1){
perror("Socket Error\n");
exit(1);
}
else
printf("Successfullly Connected to Socket: %d\n",Socket);
return Socket;
}
int bindFile(int Socket, const struct sockaddr * receiver, int len){
int Bind = bind(Socket, receiver, len);
if(Bind == -1){
perror("Bind Error\n");
exit(1);
}
else
printf("Successfullly Connected with Bind number: %d\n", Bind);
}
int listenFile(int Socket, int n){
int listen1 = listen(Socket, n);
if(listen1 == -1){
perror("listen Error\n");
exit(1);
}
else
printf("Successfully Connected with no Listen Error\n");
}
int acceptFile(int Socket, struct sockaddr * receiver, socklen_t addrlen){
int accept1 = accept(Socket, (struct sockaddr *)&receiver, &addrlen);
if(accept1 == -1){
perror("accept Error\n");
exit(1);
}
else
printf("Successfully Accepted with Data Socket number: %d\n", accept1);
}
void clearBuffer(char* b, int len) {
int i;
for (i = 0; i < len; i++)
b[i] = '\0';
sleep(0.1);
}
int main(int abcd, char *args[]) {
//Socket
int Socket = socketFile();
//Struct for Receiver
struct sockaddr_in receiver, sender;
receiver.sin_family = AF_INET;
receiver.sin_port = htons(atoi(args[1]));
receiver.sin_addr.s_addr = inet_addr("127.0.0.1");
int addrlength = sizeof(sender);
socklen_t senderLength;
//Bind
int Bind = bindFile(Socket, (const struct sockaddr *)&receiver, addrlength);
//Listen
int Listen = listenFile(Socket, 5);
char buffer[21];
clearBuffer(buffer, 20);
int message, set = 0, Select, client[30], max_client = 30, i, max_set = Socket;
fd_set readfds, fds;
struct timeval timeout;
for(i = 0; i < max_client; i++){
client[i] = 0;
}
//Clear & Add
FD_ZERO(&fds);
FD_SET(Socket, &fds);
bool stop = false;
while(!stop) {
readfds = fds;
Select = select(max_set +1, &readfds, NULL, NULL, NULL);
if (Select == -1) {
perror("Select");
break;
}
if(FD_ISSET(Socket, &readfds)) {
if(set < max_client) {
client[set] = acceptFile(Socket,(struct sockaddr *) &sender, senderLength);
FD_SET(client[set], &fds);
if(client[set] > max_set)
max_set = client[set];
set++;
}
}
for(i = 0; i < set; i++) {
if(FD_ISSET(client[i], &readfds)){
message = recv(client[i], buffer, 20, 0);
buffer[message] = '\0';
printf("%s\n", buffer);
}
}
}
close(Socket);
return 0;
}
The client part is okay but after connecting to the server and the sending the first message, the server is not able to receive the message.
I having a lot of trouble dealing with the error. So please rectify the error.
You should enable all warnings. Then you'd see the reason immediately: acceptFile does not return anything, therefore client[set] is set to garbage.

Worker thread exits some time later

Here is a simple echo program using sockets and multi threads, it compiles and runs well in my Ubuntu if the client(via telnet) and server run on the same machine, but when I remotely connect to the server via telnet from another machine, it initially runs well(echos my message back every time), but some time later, there is no echo anymore even the telnet session is still alive, i am not sure where the problem is, can someone give some hits on this? I am new to multi thread programming and socket programming, learning on that.
#define ERROR -1
#define MAX_CLIENTS 2
#define MAX_DATA 1024
void* worker(void* sockId)
{
int socketId = *(int*)sockId;
int data_len = 1;
char data[MAX_DATA];
while(data_len > 0)
{
data_len = recv(socketId, data, MAX_DATA, 0);
if (data_len > 0)
{
send(socketId, data, data_len, 0);
data[data_len] = '\0';
printf("Sent message: %s", data);
}
}
printf("Client disconnected\n");
close(socketId);
}
int main(int argc, char* argv[])
{
if (argc <= 1)
{
printf("missing argument: port\n");
exit(-1);
}
struct sockaddr_in server;
struct sockaddr_in client;
int sock;
int new_connection;
int sockaddr_len = sizeof(struct sockaddr_in);
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == ERROR)
{
perror("server socket: ");
exit(-1);
}
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[1]));
server.sin_addr.s_addr = INADDR_ANY;
bzero(&server.sin_zero, 8);
if ((bind(sock, (struct sockaddr*)&server, sockaddr_len)) == ERROR)
{
perror("bind: ");
exit(-1);
}
if ((listen(sock, MAX_CLIENTS)) == ERROR)
{
perror("listen: ");
exit(-1);
}
while(1)
{
if ((new_connection = accept(sock, (struct sockaddr*)&client, &sockaddr_len)) == ERROR)
{
perror("accpet: ");
exit(-1);
}
printf("New Client connected from port: %d and IP: %s\n", ntohs(client.sin_port), inet_ntoa(client.sin_addr));
pthread_t thread;
pthread_create(&thread, NULL, worker, (void*)&new_connection);
pthread_detach(thread);
}
close(sock);
pthread_exit(NULL);
return 0;
}
Add some logging and you'll probably find that your code is blocked in send. You use naive, sequential I/O, so if the other end of the connection stops reading data, soon you do too.

Implementation of custom message logger for windows : reports 10049 when ntwk cable unplugged

Trying to develop a simple/small syslog server for windows.
This implementation is just to store LOGS in the same machine from 2 other processes of same machine.
Wanted this to be similar to LINUX implementation.Started to use UDP DATAGRAM to send data between processes.
It is working as expected. However, it has been noticed that when NETWORK cable is unplugged the messages are not reaching to the server from client process application.
The client process reports 10049 error (When network cable is unplugged)
Request some guidance how to make this work between local process. Since, all my process run in local machine.
SERVER END LISTEN CODE:
int main(int argc,char *argv[])
{
SOCKET s;
FILE *fp;
struct sockaddr_in server, si_other;
int slen , recv_len;
char buf[BUFLEN];
WSADATA wsa;
struct stat sts;
char fileNameWithPath[512]={'\0'};
int status;
printf("ARGC %d\n",argc);
char a[10];
strcpy(logBasePath,"C:\\log\\");
if(argc == 1)
{
//parseSyslogConfiguration();
if (loggingLevel > 4)
loggingLevel=DEBUG_LOG;
}
else
{
memset(a,0,sizeof(a));
strncpy(a,argv[1],1);
int isnum=isdigit(a[0]);
printf("len argv : %d , isdigit : %d\n",strlen(argv[1]),isnum);
//parseSyslogConfiguration();
if(strlen(argv[1]) == 1 && isnum == 1)
{
loggingLevel = atoi(argv[1]);
if (loggingLevel > 4)
loggingLevel=DEBUG_LOG;
printf("Current Log level initaited : %d",loggingLevel);
}
else
{
loggingLevel=DEBUG_LOG;
printf("Invalid arg (%s)for syslog server setting log level to DEBUG\n",argv[1]);
printf("Values can be from : 0-4 \n");
}
}
if(buf[strlen(logBasePath)-1] != '\\')
{
printf("ADDING END SLASH\n");
strncat(logBasePath,"\\",1);
}
else
printf("NOT ADDING END SLASH\n");
//g_thread_init(NULL);
//write_mutex = g_mutex_new();
slen = sizeof(si_other) ;
getdatetime(&dateinfo);
strcpy(logFileName,"syslog");
memset(fileNameWithPath,0,sizeof(fileNameWithPath));
strcat(fileNameWithPath,logBasePath);
strcat(fileNameWithPath,logFileName);
//strcat(fileNameWithPath,logFileName,logBasePath,"syslog");
status = stat(fileNameWithPath, &sts);
if(errno == ENOENT)
{
fp = fopen(fileNameWithPath, "a+");
logMessage(fp,dateinfo.syslogTimeFormat,"LOGROTATE","[origin software='TEST']",0);
fclose(fp);
}
getdatetime(&dateinfo);
setSyslogFileDate(logBasePath);
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//Create a socket
if((s = socket(AF_UNIX , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
server.sin_family = AF_UNIX;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( PORT );
//Bind
if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
puts("Bind done");
//msgQueueId = g_queue_new();
//g_queue_init(msgQueueId);
// syslogFileWriteThreadId = g_thread_create(ProcessLogMsgfunc, NULL, TRUE, &error);
// syslogRotateThreadId = g_thread_create(syslogRotateMonitor, NULL, TRUE, &error);
//keep listening for data
while(1)
{
fflush(stdout);
memset(buf,'\0', BUFLEN);
if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
LOGSTRUCT *qMsg = NULL;
memset(&message,0,sizeof(LOGSTRUCT));
qMsg = malloc(sizeof(LOGSTRUCT));
memset(qMsg,0,sizeof(LOGSTRUCT));
memcpy(qMsg,&buf,sizeof(LOGSTRUCT));
PostMessageQ(qMsg);
}
// g_mutex_free(write_mutex);
// g_queue_free(msgQueueId);
closesocket(s);
WSACleanup();
// g_thread_join(syslogFileWriteThreadId);
// g_thread_join(syslogRotateThreadId);
return 0;
}
CLENT SIDE IMPLEMENTATION:
#include<stdio.h>
#include<winsock2.h>
//#include <glib.h>
#define DEBUG_LOG 0
#define TRACE_LOG 1
#define WARNING_LOG 2
#define ERROR_LOG 3
#define FATAL_LOG 4
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#define SERVER "127.0.0.1" //ip address of udp server
#define BUFLEN 4096 //Max length of buffer
#define PORT 514 //The port on which to listen for incoming data
#define RUN_SERVER 1
struct sockaddr_in si_other;
int s;
GMutex *write_mutex = NULL;
static char appLogName[128] = {'0'};
typedef enum{
LOGINIT,
LOGMESSAGE,
LOGTRACE,
LOGEXIT
}logCommand;
typedef struct
{
logCommand command;
int logLevel;
int pid;
char appName[128];
char loggerMessage[3200];
}LOGSTRUCT, *LPLOGSTRUCT;
int log_init(char *infoName,int level)
{
int ret=0;
WSADATA wsa;
//if(write_mutex == NULL)
//{
//g_thread_init(NULL);
//write_mutex = g_mutex_new();
//Initialise winsock
if(strlen(infoName) == 0 && strlen(appLogName) == 0)
{
strcpy(appLogName,"ATM");
}
else
{
strcpy(appLogName,infoName);
}
//create socket
if ( (s=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
{
printf("socket() failed with error code : %d" , WSAGetLastError());
//exit(EXIT_FAILURE);
return -1;
}
//int nOpt=1;
//setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char*)&nOpt, sizeof(int));
//setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&nOpt, sizeof(int));
//setup address structure
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
si_other.sin_addr.S_un.S_addr = INADDR_ANY;
//si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);
// si_other.sin_addr.S_un.S_addr = INADDR_BROADCAST ;
// si_other.sin_addr.s_addr = INADDR_ANY;
//}
return 0;
}
void log_exit()
{
RUN_SERVER=0;
closesocket(s);
WSACleanup();
}
void ms_log(char *buf,int priority)
{
debug_log(buf,priority);
}
void debug_log(char *buf,int priority)
{
//g_mutex_lock(write_mutex);
int ret = 0;
LOGSTRUCT log;
memset(&log,0,sizeof(LOGSTRUCT));
log.command=LOGMESSAGE;
log.logLevel=priority;
log.pid = GetCurrentProcessId();
if(strlen(appLogName))
{
strcpy(log.appName,appLogName);
}
if(strlen(buf))
{
strcpy(log.loggerMessage,buf);
ret=sendDataPacket(&log , sizeof(LOGSTRUCT));
}
//g_mutex_unlock(write_mutex);
}
int sendDataPacket(LOGSTRUCT *data , int dataLength)
{
BOOL bResult;
DWORD cbBytes;
int slen;
slen=sizeof(si_other);
if (sendto(s, data, dataLength , 0 , (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
{
printf("sendto() failed with error code : %d" , WSAGetLastError());
return -1;
}
return 0;
}
int main(void)
{
char buf[BUFLEN];
char message[BUFLEN];
WSADATA wsa;
LOGSTRUCT log;
//start communication
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
//exit(EXIT_FAILURE);
return -2;
}
printf("Initialised.\n");
log_init("TESTVEN",1);
while(RUN_SERVER)
{
printf("Enter message : ");
gets(message);
log.command = LOGMESSAGE;
strcpy(log.appName,"TESTAPP");
log.logLevel=DEBUG_LOG;
log.pid=GetCurrentProcessId();
strcpy(log.loggerMessage,message);
sendDataPacket(&log,sizeof(LOGSTRUCT));
//send the message
}
log_exit();
return 0;
}
Error code 10049 : WSAEADDRNOTAVAIL: Cannot assign requested address.
The requested address is not valid in its context. This normally results from an attempt to bind to an address that is not valid for the local computer. This can also result from connect, sendto, WSAConnect, WSAJoinLeaf, or WSASendTo when the remote address or port is not valid for a remote computer (for example, address or port 0).
So can happen with sendto as well. The remote address IP_ADDR_ANY is not a valid address any more on cable plugout?
If its on same machine, try 127.0.0.1 on server code as well?

How to reduce message dropping in UDP socket communication, using only single port?

I have writter code snippet for UDP Client and server. I am using same port for sending and receiving. My problem is that there are many messages drops at client side, so can someone help me to optimize my code, here is my code for UDP client:
#define SERVERIP "192.168.170.155"
#define SERVERPORT 5000
#define DEVICE_SEND_PORT 5000
#define DEVICE_RECEIVE_PORT 5000
#define BUFFERSIZE 2048
/**For socket file descriptor identification*/
#define S1READY 0x01
int m_SendSocketId;
int m_ReceiveSocketId;
int msgcount;
int socketbuffsize = 1*1024*1024;
/**
* FUNCTION NAME : waitToRead
* Implementation of select and non-blocking socket mechanism
* #param socket Socket that needs to be in select and non blocking mode
* #return Returnd the file descriptors which, returned by select function
*/
int waitToRead(int socket)
{
fd_set fds;
struct timeval timeout;
int rc; // number of file descriptor returned
int result; // result
int fd; // file descriptor
fd=fcntl(socket,F_GETFL,0);
fcntl(socket,F_SETFL,fd | O_NONBLOCK);
// Set time limit.
timeout.tv_sec = 1;
timeout.tv_usec = 0;
// Create a descriptor containing our sockets.
FD_ZERO(&fds);
FD_SET(socket, &fds);
rc = select(sizeof(fds)*8, &fds, NULL, NULL, &timeout);
if (rc==-1)
{
printf("[%s:%d#%s] Select Failed\n",__FILE__, __LINE__,__func__);
return -1;
}
result = 0;
if (rc > 0)
{
if (FD_ISSET(socket, &fds))
result |= S1READY;
}
return result;
}
/**
* FUNCTION NAME : receiveMessage
* This function opens particular port that is defined in the
* Configuration file, and listens on that port.
* #return if there'll be any issue in listening, then it will return
* false otherwise it will return true.
*/
bool receiveMessage()
{
struct sockaddr_in serverAddr; //Information about the Device UDP Server
struct sockaddr_in client_addr; // Information about Qgate Server
char buffer[BUFFERSIZE]; // Buffer to store incoming message
int addr_len; // to store client address length
int serverlen; // to store server address length
int sockResult; // to store result given by waitToRead
int optval = 1;
int receivedByte = 0;
//Open a datagram Socket
if((m_ReceiveSocketId = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("[%s:%d#%s] UDP Client - socket() error\n",__FILE__, __LINE__,__func__);
return false;
}
//Configure Server Address.
//set family and port
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(DEVICE_RECEIVE_PORT);
setsockopt(m_ReceiveSocketId, SOL_SOCKET,SO_REUSEADDR, &optval, sizeof(optval));
/*if (setsockopt(m_ReceiveSocketId, SOL_SOCKET, SO_RCVBUF, &socketbuffsize, sizeof(socketbuffsize)) == -1)
{
printf("Recieve Socket memory Allocation fail\n");
}*/
if((serverAddr.sin_addr.s_addr = INADDR_ANY) == (unsigned long)INADDR_NONE)
{
printf("[%s:%d#%s] Host Not found(%d)\n",__FILE__, __LINE__,__func__,h_errno);
close(m_ReceiveSocketId); // close the socket
return false;
}
if (bind(m_ReceiveSocketId, (struct sockaddr *) &serverAddr,sizeof(struct sockaddr_in)) < 0 )
{
printf("[%s:%d#%s] UDP Client- Socket Bind error=%s\n",__FILE__, __LINE__,__func__,strerror(errno));
close(m_ReceiveSocketId); // close the socket
return false;
}
serverlen = (int )sizeof(serverAddr);
addr_len = sizeof(struct sockaddr);
// Loop and listen for incoming message
while(1)
{
//wait at select to, read
sockResult = waitToRead(m_ReceiveSocketId);
if(sockResult == S1READY)
{
receivedByte = read(m_ReceiveSocketId,buffer,BUFFERSIZE);
buffer[receivedByte] = '\0';
if(receivedByte == -1)
{
printf("[%s:%d#%s] UDP Client - receive error", __FILE__,__LINE__,__func__);
close(m_ReceiveSocketId);
return false;
}
else if(receivedByte > 0)
{
//printf("[%s:%d#%s] received message = %d bytes\n",__FILE__,__LINE__,__func__,(int)strlen(buffer));
printf("count: %d, buffer %s \n", msgcount++, buffer);
}
}
memset(buffer, 0, BUFFERSIZE);
fflush(stdout);
}
close(m_ReceiveSocketId); // close the socket
printf("[%s:%d#%s] Recieve socket closed:%s\n",
__FILE__, __LINE__,__func__, strerror(errno));
return true;
}
bool sendMessage(char *message)
{
struct sockaddr_in serverAddr; //Information about the server
struct sockaddr_in deviceAddr; //Device UDP Client Address for sending message
int optval = 1;
//Open a datagram Socket
if((m_SendSocketId = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("[%s:%d#%s] UDP Client - socket() error\n",__FILE__, __LINE__,__func__);
return false;
}
// Clear out the device struct
memset(&deviceAddr, 0x00, sizeof(struct sockaddr_in));
deviceAddr.sin_family = AF_INET;
deviceAddr.sin_port = htons(DEVICE_SEND_PORT);
setsockopt(m_SendSocketId, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
/*if (setsockopt(m_SendSocketId, SOL_SOCKET, SO_SNDBUF, &socketbuffsize, sizeof(socketbuffsize)) == -1)
{
printf("send Socket memory Allocation fail\n");
}*/
if((deviceAddr.sin_addr.s_addr = INADDR_ANY) == (unsigned long)INADDR_NONE)
{
// in netdb.h
printf("[%s:%d#%s] Host Not found(%d)\n",__FILE__, __LINE__,__func__, h_errno);
close(m_SendSocketId); // close the socket
return false;
}
if (bind(m_SendSocketId, (struct sockaddr *) &deviceAddr,sizeof(struct sockaddr_in)) < 0 )
{
printf("[%s:%d#%s] UDP Client- Socket Bind error=%s\n",__FILE__, __LINE__,__func__,strerror(errno));
close(m_SendSocketId); // close the socket
return false;
}
// Clear out the server struct
memset(&serverAddr, 0x00, sizeof(struct sockaddr_in));
//Configure Server Address.
//set family and port
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(SERVERPORT);
//serverAddr.sin_addr.s_addr = htonl(39898);
if((serverAddr.sin_addr.s_addr = inet_addr(SERVERIP)) == (unsigned long)INADDR_NONE)
{
printf("[%s:%d#%s] Host Not found %d\n",__FILE__, __LINE__,__func__,h_errno);
close(m_SendSocketId);
return false;
}
// Send data to the server.
if( sendto(m_SendSocketId, message,strlen(message) ,0, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0 )
{
printf("[%s:%d#%s] UDP Client - sendto() error=%s \n",__FILE__, __LINE__,__func__,strerror(errno));
close(m_SendSocketId);
return false;
}
close(m_SendSocketId);
return true;
}
int main ()
{
int loop;
char str[10];
msgcount = 1;
pthread_t receiveThread;
if(pthread_create(&receiveThread, NULL,(void *)&receiveMessage, NULL) != 0)
{
printf("[%s:%d#%s] thread create Failed(%s)\n",
__FILE__, __LINE__,__func__, strerror(errno));
return false;
}
for(loop =0; loop < 1000; loop++)
{
sprintf(str,"%4d",loop);
sendMessage(str);
}
pthread_join(receiveThread, NULL);
return 0;
}
Here is the temporary UDP server code, it receives almost above 90% messages and also sends the same, but udpclient is not able to receive the messages.
int main()
{
int sock;
int addr_len, bytes_read, bytes_send;
char recv_data[1024];
int i;
int count=0;
struct sockaddr_in server_addr , client_addr;
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("Socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5000);
server_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(server_addr.sin_zero),8);
//client_addr.sin_family = AF_INET;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
if (bind(sock,(struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1)
{
perror("Bind");
exit(1);
}
addr_len = sizeof(struct sockaddr);
printf("\nUDPServer Waiting for client on port 5000");
fflush(stdout);
while (1)
{
bytes_read = recvfrom(sock,recv_data,1024,0,(struct sockaddr *)&client_addr, (socklen_t *)&addr_len);
recv_data[bytes_read] = '\0';
if(recv_data[0]!=0x07)
{
recv_data[0] = 0x09;
//client_addr.sin_port = htons(51254);
bytes_send = sendto(sock, recv_data, bytes_read, 0, (struct sockaddr *)&client_addr, (socklen_t)sizeof(client_addr));
if(bytes_send < 0 )
{
perror("send to ");
}
printf("\nNumber %d", ++count);
memset(&recv_data, 0x00, 1024);
}
else
{
printf("Received Keep ALive\n");
}
memset(&client_addr, 0x00, sizeof(struct sockaddr_in));
fflush(stdout);
}
return 0;
}
Any help would be highly appreciated.
Thanks Yuvi
Your code has nothing to do with UDP dropping packets, except possibly that you are sending packets too fast for the network or the receiver. UDP isn't reliable. It drops packets. If your application protocol requires no dropped packets, you have to build in reliability at that level, via an ACK-based or NACK-based protocol with retries.
Or use TCP like everybody else does in this situation.
The problem was in sendMessage Function, here I was recreating socket every time when I need to send message, and I think that takes time. I don't know yet which is calls are blocking but making sending socket resolves my problem. Now the dropping of message is upto 20 to 30 % only.

Resources