UDB peer to peer on the same machine - c++

I want to make sure that I understand the concept
we have example.exe and we will run it 5 times or more on the same computer
example.exe will create a pear (which has a sending and receiving socket)
and the sending socket sends on a fixed port and the receiving socket receive on the same port
my question is that when running example.exe 5 times
5 peers will be created on the same "machine" with the same fixed port !!! how that comes !
and i tried the code and it is working on the machine which means the same Ip address!
here are some code
Receiving Socket
sockaddr_in RecvAddr;
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(PORT);
RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
cout << RecvAddr.sin_addr.s_addr << endl;
int broadcastValue = 1;
if (setsockopt(receivingSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&broadcastValue, sizeof(broadcastValue)) == SOCKET_ERROR)
exit(EXIT_FAILURE);
int iResult = 0;
iResult = bind(receivingSocket, (SOCKADDR *)& RecvAddr, sizeof (RecvAddr));
if (iResult != 0) {
exit(EXIT_FAILURE);
Sending Socket
sockaddr_in destinationAddress;
destinationAddress.sin_family = AF_INET;
destinationAddress.sin_addr.s_addr = INADDR_BROADCAST;
destinationAddress.sin_port = htons((unsigned short)PORT);
if (sendto(sendingSocket, message.c_str(), message.length(), 0, (struct sockaddr*) &destinationAddress, sizeof(destinationAddress)) == SOCKET_ERROR)
{
exit(EXIT_FAILURE);
}

Related

Can't receive UNICAST packet over WiFi using INADDR_ANY

I have a device broadcasting over ethernet, using the code below this successfully receives the packets. The device also unicasts the same packet over WiFi but this is not received (Disabling all other interfaces except WiFi in windows I get a timeout error). If I change:
address.sin_addr.s_addr = htonl(INADDR_ANY);
to
address.sin_addr.s_addr = inet_addr("192.168.0.13");
Which is the address of the wifi interface it does receive the packets. The packets over both ethernet and WiFi can be seen in WireShark, the only difference between them are the destination addresses (broadcast and unicast) and the ttl.
Here is the code:
int main()
{
int iResult;
char recv_buf[4000];
int opt = 1;
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
printf("WSAStartup failed with error: %d\n", err);
return 1;
}
SOCKET handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
int return_code = 0;
return_code = setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char *>(&opt), sizeof(opt));
std::cout<<"socket option 1 return:" << return_code << std::endl;
DWORD tv = 100;
return_code = setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<char *>(&tv), sizeof(tv));
std::cout << "socket option 2 return:" << return_code<< std::endl;
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_port = htons(3000);
address.sin_addr.s_addr = htonl(INADDR_ANY);
//address.sin_addr.s_addr = inet_addr("192.168.0.13"); //this works
memset(&address.sin_zero, 0, sizeof(address.sin_zero));
std::cout << "bind return:" << bind(handle, (const sockaddr *)&address, sizeof(sockaddr_in)) << std::endl;
// Receive data until the server closes the connection
do {
Sleep(5000);
iResult = recv(handle, recv_buf, 4000, 0);
if (iResult > 0)
printf("Bytes received: %d\n", iResult);
else if (iResult == 0)
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
} while (true);
return 0;
}

recvfrom() doesn't get any UDP messages

I'm trying to get UDP messages that are being sent from different applications on my machine.
I created a socket and bind it to an address. When I send UDP messages using Packet Sender, nothing arrives. I tried disabling the firewall just to be sure, and still nothing happens.
I send messages to 127.0.0.1 port 8034.
I tried binding to both 127.0.0.1 and INADDR_ANY, neither work.
This is the code I'm using to listen :
SOCKET SendSocket = INVALID_SOCKET;
sockaddr_in RecvAddr, ClientAddr;
WSADATA wsaData;
struct sockaddr_in serv, client;
int l = sizeof(client);
char buffer[256];
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup failed with error: %d\n", iResult);
}
SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (SendSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
}
ClientAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
ClientAddr.sin_family = AF_INET;
ClientAddr.sin_port = htons(8034);
bind(SendSocket, (struct sockaddr *) &ClientAddr, sizeof(ClientAddr));
bool valid = true;
while( valid )
{
//cout << "\ngoing to recv\n";
int rc = recvfrom(SendSocket, buffer, sizeof(buffer), 0, (struct sockaddr *)&client, &l);
if (rc < 0)
{
//cout << "ERROR READING FROM SOCKET";
}
else
{
cout << "\n the message received is : " << buffer << endl;
}
DoPostDrawTask( valid );
}

C++ winsock TCP listening

I have a software that decodes ADS-B messages (from planes) and sends results in hexadecimal to a port (47806).
I would like to listen to this port to show that data, so I wrote this :
WSADATA WSAData;
WSAStartup(MAKEWORD(2, 0), & WSAData);
SOCKET sock;
SOCKADDR_IN socket_in;
socket_in.sin_addr.s_addr = htonl(INADDR_ANY);
socket_in.sin_family = AF_INET;
socket_in.sin_port = htons(47806);
sock = socket(AF_INET, SOCK_STREAM, 0);
bind(sock, (SOCKADDR*)& socket_in, sizeof(socket_in));
listen(sock, 0);
int valid = 0;
while (TRUE) {
int size_socket_in = sizeof(socket_in);
valid = accept(sock, (SOCKADDR*)& socket_in, & size_socket_in);
if (valid != INVALID_SOCKET) {
std::cout << "OK";
}
}
This code should display "OK" each time a message is received, but it doesn't.
I can read data with a Telnet software, like PuTTY :
PuTTY telnet on port 47806
I don't understand why my code doesn't work.
Here's the right code :
WSADATA WSAData;
WSAStartup(MAKEWORD(2, 0), & WSAData);
SOCKET sock;
SOCKADDR_IN socket_in;
InetPton(AF_INET, "127.0.0.1", & socket_in.sin_addr.s_addr);
socket_in.sin_family = AF_INET;
socket_in.sin_port = htons(47806);
sock = socket(AF_INET, SOCK_STREAM, 0);
connect(sock, (SOCKADDR*)& socket_in, sizeof(socket_in));
int valid = 0;
char buffer[512] = "";
while (TRUE) {
valid = recv(sock, buffer, sizeof(buffer), 0);
if (valid != INVALID_SOCKET) {
std::cout << buffer;
}
}
My program is a client and not a server. So I have to define an IP adress with InetPton, connect to the server with connect and receive the messages with recv.
Thank you #Hasturkun and #RustyX for help and explanations.

c++ UDP relay application latency

I want to receive UDP packets from a server application (on the same computer) and forward it to an UDP receive app on a different port.
The server app is not mine, nor do i have the source code.
The UDP receive app is a Java application.
If i bind the Java application directly to the server app port, there is very low latency, but if i connect it to the relay appĀ“port i get almost one second of delay.
The receiving port has to be non-blocking.
#define rcv_length 160
fd_set fds;
int n;
struct timeval tv;
void CMClient::startUDPListener(){
CMport_number = 32200;
remoteAddrLen = sizeof(struct sockaddr_in);
if (WSAStartup(0x0101, &CMw) != 0)
{
fprintf(stderr, "Could not open Windows connection.\n");
exit(0);
}
CMsd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (CMsd == INVALID_SOCKET)
{
fprintf(stderr, "Could not create socket.\n");
WSACleanup();
exit(0);
}
CMserver.sin_family = AF_INET;
CMserver.sin_port = htons(CMport_number);
CMserver.sin_addr.s_addr = inet_addr("127.0.0.1");
long rc=bind(CMsd,(SOCKADDR*)&CMserver,sizeof(SOCKADDR_IN));
if(rc==SOCKET_ERROR)
{
printf("Error: bind code: %d\n",WSAGetLastError());
}
}
void CMClient::updateData(UDPServer* svr, int CMnr){
FD_ZERO(&fds);
FD_SET(CMsd, &fds);
tv.tv_sec = 0;
tv.tv_usec = 1;
n = select ( CMsd, &fds, NULL, NULL, &tv ) ;
if (FD_ISSET(CMsd, &fds))
{
FD_CLR(CMsd,&fds);
char* rcvBuffer = new char[rcv_length];
long rc=recv(CMsd,rcvBuffer,rcv_length,0); //receive
if(rc!=SOCKET_ERROR)
{
rcvBuffer[0] = CMnr;
sendto(svr->sd, (char*)rcvBuffer, rcv_length, 0, (struct sockaddr*)&svr->server, sizeof(svr->server)) != (int)sizeof(rcvBuffer); //send
}
if(rcvBuffer)
delete [] rcvBuffer;
}
}
The UDP server to send to the Java application is initialized as follows:
void UDPServer::startUDPServer(){
if (WSAStartup(0x0101, &w) != 0)
{
fprintf(stderr, "Could not open Windows connection.\n");
exit(0);
}
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd == INVALID_SOCKET)
{
fprintf(stderr, "Could not create socket.\n");
WSACleanup();
exit(0);
}
server.sin_family = AF_INET;
server.sin_port = htons(port_number);
server.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == -1)
{
fprintf(stderr, "Could not connect name to socket.\n");
stopUDPServer();
}
}
The main calls
UDPServer* udpsvr;
udpsvr = new UDPServer;
udpsvr->startUDPServer();
while(1){
CM->updateData(udpsvr, CMid);
}
Any help would be appreciated why i get that much delay.
The data received from the Java app is correct but ~1 second delay.
Thank you,
Regards
Don't use bind() on client. Use connect().
Summing up, for UDP:
Server:
socket()
bind()
Client:
socket()
connect()
Example of code for server:
// socket()
fd_ = socket(AF_INET, SOCK_DGRAM, 0);
if (fd_ < 0) {
throw std::runtime_error ("Client socket error");
}
// connect()
struct sockaddr_in serv_addr;
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
struct in_addr addr;
inet_aton(address.c_str(), &addr);
bcopy(&addr, &serv_addr.sin_addr.s_addr, sizeof(addr));
if (connect(fd_, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0) {
::close(fd_);
throw std::runtime_error ("Client socket error");
}
Example of code for client:
// socket()
fd_ = socket(AF_INET, SOCK_DGRAM, 0);
if (fd_ < 0) {
throw std::runtime_error ("Client socket error");
}
// connect()
struct sockaddr_in serv_addr;
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
struct in_addr addr;
inet_aton(address.c_str(), &addr);
bcopy(&addr, &serv_addr.sin_addr.s_addr, sizeof(addr));
if (connect(fd_, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0) {
::close(fd_);
throw std::runtime_error ("Client socket error");
}
Finally, you may want to have a look at flushing UDP buffers.

trying to broadcast through udp socket

I've bumped into a problem with my broadcasting server. basically, I want it to send broadcasts continuously from the moment I launch it. for some reason it will not start until it receives a connection from somewhere. I must have messed up something but I can't realise what.
here is my code:
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET sock;
sock = socket(AF_INET, SOCK_DGRAM, 0);
char broadcast = 'a';
if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0)
{
perror("broadcast options");
closesocket(sock);
return 1;
}
struct sockaddr_in Recv_addr;
struct sockaddr_in Sender_addr;
int len = sizeof(struct sockaddr_in);
char recvBuff[50];
int recvBuffLen = 50;
//char sendMsg[] = "broadcast message from salam rofl";
Recv_addr.sin_family = AF_INET;
Recv_addr.sin_port = htons(PORT);
Recv_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(sock, (sockaddr*)&Recv_addr, sizeof(Recv_addr)) < 0)
{
perror("bind");
_getch;
closesocket(sock);
return 1;
}
//recvfrom(sock, recvBuff, recvBuffLen, 0, (sockaddr *)&Sender_addr, &len);
//cout << "\nreceived message: " << recvBuff;
while(1)
{
Sleep(3000);
//_getch();
getTime();
if(sendto(sock, currentTime, strlen(currentTime)+1, 0, (sockaddr *)&Sender_addr, sizeof(Sender_addr)) < 0)
{
perror("borhot send: ");
_getch();
closesocket(sock);
return 0;
}
else cout << "message sent successfully";
}
_getch;
closesocket(sock);
WSACleanup();
return 0;
basically if I remove recvfrom, it will give me a send error ("No error") which simply puzzles me. also, if I send it something with a client, it will start broadcasting, but if I connect with another client, only the first client is receiving the broadcast.
thank you in advance.
I doubt it matters but I'm trying to broadcast the current time.
You are not initializing Sender_Addr so you are not telling sendto() where to actually broadcast to.
Try this instead:
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET)
{
perror("socket creation");
_getch;
return 1;
}
BOOL enabled = TRUE;
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&enabled, sizeof(BOOL)) < 0)
{
perror("broadcast options");
_getch;
closesocket(sock);
return 1;
}
struct sockaddr_in Sender_addr;
Sender_addr.sin_family = AF_INET;
Sender_addr.sin_port = htons(BROADCAST_PORT);
Sender_addr.sin_addr.s_addr = inet_addr("Broadcast IP Here");
struct sockaddr_in Recv_addr;
Recv_addr.sin_family = AF_INET;
Recv_addr.sin_port = htons(PORT);
Recv_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (sockaddr*)&Recv_addr, sizeof(Recv_addr)) < 0)
{
perror("bind");
_getch;
closesocket(sock);
return 1;
}
while(1)
{
Sleep(3000);
getTime();
if (sendto(sock, currentTime, strlen(currentTime)+1, 0, (sockaddr *)&Sender_addr, sizeof(Sender_addr)) < 0)
{
perror("borhot send: ");
_getch();
closesocket(sock);
return 0;
}
cout << "message sent successfully";
}
_getch;
closesocket(sock);
WSACleanup();
return 0;
Looks like your Sender_addr is never being initialized, thus when you remove the recvfrom you're getting an error, and when the recvfrom is in place it's getting populated with the address of the first client to connect (but never being updated).
If you don't know the addresses of the clients that you want to broadcast to, you'll need to setup some handshake where they send you a ping, you receive it with recvfrom, and you store their address in a list or something. Then, when you broadcast, you need to send your message to every client address in the list.