throughput control via Sleep - c++

I have this code, the point is that I want to receive no more than 600Kbits/s using a UDP socket, I implemented an algorithm using duration during which we receive and the sleep command....
#if defined (WIN32)
#include <winsock2.h>
typedef int socklen_t;
#elif defined (linux)
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(s) close(s)
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
#endif
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define RCVBUFSIZE 4
#define PORT 4444
#define ECHOMAX 255
int main(void)
{
#if defined (WIN32)
WSADATA WSAData;
int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
#else
int erreur = 0;
#endif
int recvMsgSize;
char echoBuffer[RCVBUFSIZE];
//unsigned int echoStringLen;
//int bytesRcvd, totalBytesRcvd; //bytes received in a single recv()
SOCKET sock;
SOCKADDR_IN sin;
SOCKADDR_IN SenderAddr;
int SenderAddrSize = sizeof(SenderAddr);
if(!erreur)
{
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
sin.sin_family = AF_INET;
sin.sin_port = htons(4444);
memset(&sin.sin_zero, '\0', sizeof(sin.sin_zero));
bind(sock, (SOCKADDR*)&sin, sizeof(sin));
//totalBytesRcvd = 0;
printf("Received: ");
int speed_limit= 614400; //600Kbits/s
int one_second=1000;
int elapsed; //elapsed time
int transmit=0; // how much i receive during 'elapsed'
int expected_receive; //what I'm excpected to receive
int transmit_delta; //diference
int time_sleep; //how much to sleep
clock_t start_time= clock();
for(;;)
{
if((recvMsgSize=recvfrom(sock, echoBuffer,1024, 0, (SOCKADDR *)&SenderAddr, &SenderAddrSize)) > 0)
{
transmit+=recvMsgSize;
clock_t tempo= clock();
elapsed=(tempo-start_time)/CLOCKS_PER_SEC;
// Check moment speed every five second, you can choose any value
if(elapsed>5)
{
start_time= tempo;
expected_receive=speed_limit*elapsed/8;
transmit_delta=expected_receive-transmit;
if(transmit_delta>0)
{
time_sleep=8*transmit_delta*one_second/speed_limit;
Sleep(time_sleep);
}
transmit=0;
}
echoBuffer[recvMsgSize]='\0';
printf(echoBuffer);
}
}
printf("\n");
getchar() ;
closesocket(sock);
#if defined (WIN32)
WSACleanup();
#endif
}
return EXIT_SUCCESS;
}
the problem is that it receive the message but it blocks the receiving process from time to time...which I guess will cause loss of data especially when I'm using UDP...
any alternative solution is welcolme...
thanks in advance..

Better not to sleep - just read and discard data while you are over the threshold, then resume processing it once you are ready to do so (after interval expires).

If the data is arriving over UDP, there is no way to reduce the throughput at the receiving end. You'd have to tell the sending computer to send less data. The receiver's only choice is the receive the UDP packets, or let them get dropped, and do something with them, or not.
If you use TCP, then the TCP protocol includes a built-in way to do what you want (called "source quench") ... the TCP protocol layer of the receiver will send a message to the sender telling the sender to slow down if the receiver is having problems keeping up. (and you can influence whether "the receiver is having problems keeping up" by reading the data slower than usual, if you want).

If you use non-blocking sockets with select() you can just ignore the data until you're ready to read it. Not reading data will cause the TCP connection to "slow down". However, this way you do not have exact control about the amount of data received. It's just an approximation. All techniques I know of that limit bandwidth in a more accurate way are implemented on the sender side.

Related

TCP need to discard info on the buffer or make it faster

I am making a 3d application that works with the data of the accelerometer and gyroscope of the mobile. The problem is that the mobile sends data faster than the computer reads. The application increasingly makes the movements of the mobile with more delay as time passes. For example, at the beginning 2~3s is faithful to what the mobile does in reality, but over 10s it is making the movements that I did 6 seconds before.
I understand that it is reading data from the beginning buffer while the front of the most current data grows and never reaches it. I think the problem is how I read the data that comes to me.
Here is an example code that is implemented in the application. What could I do?
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <fcntl.h>
#include <algorithm>
#define PORT 8080
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
const char *ACK = "ACKDAT\n";
std::string data;
socklen_t len;
char *error;
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
fcntl(new_socket, F_SETFL, O_NONBLOCK);
while(true){
valread = read( new_socket , buffer, 1024);
for(int i = 0;i < 1024 ; i++){
if(buffer[i]!=0){
data = data + buffer[i];
}
buffer[i]=0;
}
if(!data.empty()){
//remove /n from data
data.erase(std::remove(data.begin(), data.end(), '\n'), data.end());
std::cout<<"#"<<data<<"#"<<std::endl;
send(new_socket , ACK , strlen(ACK) , 0 );
}
data.clear();
}
return 0;
}
While Sam Varshavchik's suggestion of using a thread is good, there's another option.
You already set your socket to non-blocking with fcntl(new_socket, F_SETFL, O_NONBLOCK);. So, at each loop you should read everything there is to read and send everything there is to send. If you don't tie one-to-one the reading and writing, both sides will be able to catch up.
The main hint that you need to fix this is that you don't use the read return value, valread. Your code should look like:
while(true){ // main loop
...
valread = read( new_socket , buffer, 1024);
while(valread > 0)
{
// deal with the read values.
// deal with receiving more than one packet per iteration
}
// send code done a single time per loop.
There still plenty of architecture you need to have a clean resilient main loop that sends and receives, but I hope that points you in a useful direction.
You can have all reading from the socket done in a separate std::thread, that does nothing but read from the socket and save the data in your program's internal buffer. Your existing program reads from the internal buffer, rather than a socket, whenever it is capable of doing so.
If the internal buffer is full you'll have to figure out what to do about it, probably discard unwanted data. Perhaps stash a copy of the most recent received record, in a safe place, and put it into the buffer when things get unclogged. The dedicated execution thread will likely need to do some minimal processing, to parse the raw data from the socket into some meaningful, logical form. It's unlikely that you can simply throw away random parts of the raw data stream from the socket. It will need to be logically parsed, in some form or fashion that's particular to your application, so this can be done in a meaningful way.
You will need to implement your application's buffer in a thread-safe manner, so that it can be simultaneously accessed by multiple execution threads. If you're not familiar with multi-threaded programming in C++, you will find more information in your C++ textbook, on this topic.

What information can I get from a socket connected to a server using c++ and windows?

I have a server and when a client connects to the server, I want to take all the information from the client and make a struct with it.
What information can I get?
I know that I can get the ipv4 and port from the client, there is anything left that I can get?
This is a short way of doing it:
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT 32406
int main()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
sockaddr_in hint;
hint.sin_addr.S_un.S_addr = INADDR_ANY;
hint.sin_port = htons(DEFAULT_PORT);
hint.sin_family = AF_INET;
SOCKET listeningSocket = socket(AF_INET, SOCK_STREAM, 0);
bind(listeningSocket, (sockaddr*)&hint, sizeof(sockaddr_in));
listen(listeningSocket, SOMAXCONN);
sockaddr_in socketInfo;
int socketInfoLen = sizeof(socketInfo);
SOCKET clientSocket = accept(listeningSocket, (sockaddr*)&socketInfo, &socketInfoLen);
std::cout << inet_ntoa(socketInfo.sin_addr) << std::endl;
std::cout << socketInfo.sin_port << std::endl;
shutdown(clientSocket, SD_BOTH);
closesocket(clientSocket);
closesocket(listeningSocket);
WSACleanup();
return 0;
}
There is a whole lot of information available from getsockopt. It is a superset of what the other answer claims, for example
SO_BSP_STATE Returns the local address, local port, remote address, remote port, socket type, and protocol used by a socket.
Since you have a TCP socket you will be particularly interested in
IPPROTO_TCP socket options
There is different information available through WSAIoctl, for example
TCP_INFO_v1 structure
Some of these details will be local socket options (such as blocking or non-blocking), others will relate to the connection itself (e.g. negotiated window size). Some information about the remote client will be revealed, although not as much as if you used a bespoke fingerprinting tool.
Here is the implementation of #Ben Voigt's answer, if someone needs it:
#include <WinSock2.h>
#pragma comment (lib, "Ws2_32.lib")
bool GetSocketState(SOCKET sock, CSADDR_INFO& state) {
union CSADDR_INFO_PADDED {
CSADDR_INFO csaddr;
TCHAR padding[128];
} csaddrPadded {};
int infoLen = sizeof(csaddrPadded);
if (getsockopt(sock, SOL_SOCKET, SO_BSP_STATE, (TCHAR*)&csaddrPadded, &infoLen)) {
return false;
}
state = csaddrPadded.csaddr;
return true;
}
The only information you get that the client doesn't explicitly send is the sockaddr_in structure, ie the port and source IP address. Though of course you only get this when the client initiates a transfer (sends a packet with UDP or connects with TCP).
To get anything else, the client needs to send it as part of regular communication.

iOS UDP socket "sendto" can't send immediately one by one

I found that the behavior of iOS socket "sendto" interface was different from android or linux kernel. When we call "sendto",we start wireshark capture at the same time . But we can't find the capture data immediately. We make a test that we continuously sending 332 bytes by "sendto" per 40ms interval.And we found that all data packets was send to the network in a short central time instead of a 40MS(or above) intervals. We doubt that the ios kernal made some change for udp.Also it may calls audio delay about 900-1000ms.
I have test in iphone 5s & iphone 6,iOS 10 or 11 by demo use "sendto" api
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <sys/types.h>
int sSock = socket(AF_INET,SOCK_DGRAM,0);
struct sockaddr_in localAddr;
localAddr.sin_family = AF_INET;
localAddr.sin_port = htons(1001);
localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sSock, (struct sockaddr*)&localAddr, sizeof(localAddr)) < 0)
{
NSLog(#"bind error");
return;
}
struct sockaddr_in sendAddr;
sendAddr.sin_family = AF_INET;
sendAddr.sin_port = htons(21000);
inet_pton(AF_INET, "114.190.105.220", &sendAddr.sin_addr);
char sendBuf[332] = {0};
//unsigned char service_type = 0xe0 | IPTOS_LOWDELAY | IPTOS_RELIABILITY;
int service_type = 0x10;
int priority = 6;
//if(setsockopt(sSock, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority))<0)
if(setsockopt(sSock,IPPROTO_IP,IP_TOS,(void*)(&service_type),sizeof(service_type)) < 0)
{
NSLog(#"setsockopt failed1,error[%s]",strerror(errno));
}
while(true)
{
sendto(sSock, sendBuf, sizeof(sendBuf), 0, (struct sockaddr*)&sendAddr, sizeof(sendAddr));
time_t timeNow;
time(&timeNow);
struct tm tmNow;
struct timeval tvNow;
localtime_r(&timeNow,&tmNow);
gettimeofday(&tvNow, NULL);
char sTime[256] = {0};
snprintf(sTime, sizeof(sTime)-1, "%04d%02d%02d %02d%02d%02d.%d",tmNow.tm_year+1900,tmNow.tm_mon,tmNow.tm_mday,tmNow.tm_hour,tmNow.tm_min,tmNow.tm_sec,tvNow.tv_usec/1000);
NSLog(#"[%s]interval 40ms send",sTime);
usleep(40*1000);
}
all data packets was send to the network in a short central time instead of a 40MS(or above) intervals.
all packets send at once,wireshark capture like this:
No. Time Protocol
819 41.439392 H264
820 41.439617 H264
821 41.439819 H264

Raspbian C++ Error: expected primary expression before 'struct'

I am trying to write a program for my raspberry pi that changes its system time to the time from a GPS unit on the same network. The GPS sends out a 72 byte UDP packet across port 3000. I am new to socket programming so I am unsure where I am going wrong.
The trouble that I am having is that I can't seem to get it to build with g++. I am getting the following error:
So the main error seems to be in the line
char A = struct sockaddr_in address;
Here is the start of my program and the method where I create the socket and where the error is located, if you would like the main method of my program then I will add it too.
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include <math.h>
// defines the socket used by the GPS
#define PORT 3000
/****************************/
int CreateSocket(int port)
/****************************/
{
// Create an UDP-socket
int sock = socket(AF_INET, SOCK_DGRAM, 0);
// Check if UDP-socket was created
if(sock==-1)
{
fprintf(stderr, "1CreateSocket: socket failed\n");
return -1;
}
// Bind it to the local IP-address
struct sockaddr_in address;
char A = struct sockaddr_in address;
fprintf(stderr, A);
// Pointer to the block of memory to fill with address data
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET; // Address family for IP-address
address.sin_addr.s_addr = htonl(INADDR_ANY); // converts the unsigned integer hostlong from host byte order to network byte order
address.sin_port = htons(port); // converts the unsigned short integer hostshort from host byte order to network byte order
// Check if IP-address is correct, if not Socket failed. Otherwise it returns the socket
if(bind(sock, (struct sockaddr *) &address, sizeof(address))==-1)
{
fprintf(stderr, "2CreateSocket: bind failed\n");
close(sock);
return -1;
}
return sock;
}
Can anyone see any obvious errors here? Thanks
You don't really need these two lines:
char A = struct sockaddr_in address;
fprintf(stderr, A);
You can delete them, since they don't do anything useful, and they have a syntax error.
And to do some extra cleanup, the comment of the binding above those lines that can be deleted should actually go above the call to bind().

Unable to transmit fast via UDP broadcast on a wireless network

I have the written the following code for transmitting UDP packets via broadcasting on a wireless network. The application that I have trying to develop requires the packets to be transmitted very fast, but unfortunately I cannot do so and need to add a sleep time. I find that below 500us sleep time, I am unable to send all the packets successfully.
Why does the sleep time have to be so high?
Is it possible to reduce this time by further optimization of this code?
If I do not process the received packets buffer, is it okay? Or does this create problems?
Note that I am running this code on a wireless radio which runs using OpenWrt.
Thanks in advance.
Code:
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <netdb.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <sys/time.h>
#include <arpa/inet.h> /* for sockaddr_in */
#define BROADCAST_IP "192.168.255.255"
#define BROADCAST_PORT 45454
int b_sock=-1;
void init_socket()
{
unsigned short b_port = BROADCAST_PORT;
struct sockaddr_in b_addr;
int broadcastPermission;
char* rx_ip = BROADCAST_IP;
if ((b_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
perror("socket() failed");
/* Set socket to allow broadcast */
broadcastPermission = 1;
if (setsockopt(b_sock, SOL_SOCKET, SO_BROADCAST, (void *) &broadcastPermission, sizeof(broadcastPermission)) < 0)
perror("setsockopt() failed");
int opts;
opts = fcntl(b_sock,F_GETFL);
if(opts < 0)
perror("fcntl get failed");
opts = (opts | O_NONBLOCK);
if(fcntl(b_sock,F_SETFL,opts) < 0)
perror("fcntl set failed");
memset(&b_addr, 0, sizeof(b_addr)); /* Zero out structure */
b_addr.sin_family = AF_INET; /* Internet address family */
b_addr.sin_addr.s_addr = inet_addr(rx_ip);/* Broadcast IP address */
b_addr.sin_port = htons(b_port); /* Broadcast port */
if (bind(b_sock, (struct sockaddr *) &b_addr, sizeof(b_addr)) < 0)
perror("rx bind() failed");
}
void send_thread_body(long int buf, struct sockaddr_in tx_addr)
{
if(sendto(b_sock, &buf, sizeof(long int), 0, (struct sockaddr *)&tx_addr, sizeof(tx_addr)) < 0)
printf("tx sent diff num bytes than expected: %d\n",buf);
}
int main(int argc, char *argv[])
{
init_socket();
{
timeval start, end;
double diff = 0;
long int num = 0;
char *tx_ip = BROADCAST_IP;
unsigned short tx_port = BROADCAST_PORT;
struct sockaddr_in tx_addr;
memset(&tx_addr, 0, sizeof(tx_addr)); /* Zero out structure */
tx_addr.sin_family = AF_INET; /* Internet address family */
tx_addr.sin_addr.s_addr = inet_addr(tx_ip);/* Broadcast IP address */
tx_addr.sin_port = htons(tx_port); /* Broadcast port */
double next = 0;
double st = 0;
while (num<50000)
{
while (st <= next)
{
gettimeofday(&start,NULL);
st = start.tv_sec*1000 + ((double)start.tv_usec)/1000.0;
}
send_thread_body(num,tx_addr);
gettimeofday(&end, NULL);
diff += ((double)(((end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec))))/1000000.0;
num++;
next = end.tv_sec*1000 + ((double)end.tv_usec)/1000.0 + 0.7;
}
printf("Avg time diff: %f\n",diff/50000.0);
}
close(b_sock);
return 0;
}
You are probably overflowing the socket buffer because you set the socket to O_NONBLOCK. Normally (when blocking is enabled), if the socket buffer is full, sendto blocks until there is sufficient buffer space to hold the message for sending.
From http://pubs.opengroup.org/onlinepubs/009695399/functions/sendto.html:
If space is not available at the
sending socket to hold the message to
be transmitted and the socket file
descriptor does not have O_NONBLOCK
set, sendto() shall block until space
is available. If space is not
available at the sending socket to
hold the message to be transmitted and
the socket file descriptor does have
O_NONBLOCK set, sendto() shall fail.
When you added sleeps between your sendto calls, you were effectively throttling down the throughput and preventing the socket buffers from overflowing.
Instead of sleep, you should use a blocking socket. If the socket buffers become full, sendto will block, which is effectively the same thing as sleeping, except that it will automatically stop sleeping the instant the socket is able to hold your next datagram.
To achieve better thoughput, try lumping data into datagrams close to the MTU size (while taking care to save enough room for UDP/IP headers). This should give you smaller header overhead compared to sending very short datagrams.