C++ winsock TCP listening - c++

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.

Related

Why does this minimal HTTP test server fail half of the time?

I'm trying to write a minimal HTTP server on Windows and see the response in Chrome with http://127.0.0.1/5000. The following code works sometimes ("Hello World"), but the request fails half of the time with ERR_CONNECTION_ABORTED in Chrome (even after I restart the server). Why?
Error:
#include <winsock2.h>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")
int main()
{
WSADATA WSAData;
SOCKET sock, csock;
SOCKADDR_IN sin, csin;
WSAStartup(MAKEWORD(2,0), &WSAData);
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_family = AF_INET;
sin.sin_port = htons(5000);
bind(sock, (SOCKADDR *) &sin, sizeof(sin));
listen(sock, 0);
while(1)
{
int sinsize = sizeof(csin);
if((csock = accept(sock, (SOCKADDR *) &csin, &sinsize)) != INVALID_SOCKET)
{
std::string response = "HTTP/1.1 200 OK\nConnection: close\nContent-Length: 11\n\nHello World";
send(csock, response.c_str(), response.size(), 0);
std::cout << "done";
closesocket(csock);
}
}
return 0;
}
You fail to read the client's request before closing the connection. This usually results in the server sending a RST back to the client, which can cause the ERR_CONNECTION_ABORTED when it is processed before the response itself was processed.
As observed by another (deleted) answer, this can be "mitigated" by adding some short delay before the connection is closed, so that the response is processed by the client.
The right fix is to read the request from the client, though.
Apart from that, your response is not valid HTTP since you use \n instead of \r\n as line end and header end.
Working solution:
#include <winsock2.h>
#include <iostream>
#define DEFAULT_BUFLEN 8192
#pragma comment(lib, "ws2_32.lib")
int main()
{
char recvbuf[DEFAULT_BUFLEN];
WSADATA WSAData;
SOCKET sock, csock;
SOCKADDR_IN sin, csin;
WSAStartup(MAKEWORD(2,0), &WSAData);
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_family = AF_INET;
sin.sin_port = htons(5000);
bind(sock, (SOCKADDR *) &sin, sizeof(sin));
listen(sock, 0);
while (1)
{
int sinsize = sizeof(csin);
if ((csock = accept(sock, (SOCKADDR *) &csin, &sinsize)) != INVALID_SOCKET)
{
recv(csock, recvbuf, DEFAULT_BUFLEN, 0);
std::string response = "HTTP/1.0 200 OK\r\nConnection: close\r\nContent-Length: 11\r\n\r\nHello World";
send(csock, response.c_str(), response.size(), 0);
std::cout << "done";
closesocket(csock);
}
}
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 );
}

UDB peer to peer on the same machine

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);
}

clean and reuse open port. winsock c++

I am working on a client-server application where I have two different ports, one (principal) for us send and receive messages or any other order, and another one to send and receive screenshots of the server to the client. From client to server notice to start us send'll catch and showing in a new window ... works fine but if I close the window and open it again then and I can not connect to that port (bind fails me).
MY question is how do I clean or completely release the port I use for screenshots without affecting the main port, that is, when you close the window to release the port as if I had never used and advise the client to do the same.
Here I leave the code:
Server:
int serviceCapture(int port)
{
int error;
WSAData wsaDataER;
error = WSAStartup(MAKEWORD(2, 2), &wsaDataER);
if (error == SOCKET_ERROR)
{
return 1;
}
// ShowMessage ("Server: WinSocket Started Correctly!\n");
sock_ER = socket(AF_INET, SOCK_STREAM, 0);
if (sock_ER == SOCKET_ERROR)
{
return 2;
}
struct sockaddr_in escritorioRem; // New! Our network socket structure
escritorioRem.sin_family = AF_INET; // Always have ti as this for internet
escritorioRem.sin_port = htons(puerto); // Dont forget the byte ordering
escritorioRem.sin_addr.s_addr = INADDR_ANY;internet
if(!enviandoCapturas){
error = bind(sock_ER, (sockaddr*)&escritorioRem, sizeof(escritorioRem)); // Attempt to bind the socket
if (error == SOCKET_ERROR)
{
return 3 ;
}
}
error = listen(sock_ER, 1); // Listen for connections
if (error == SOCKET_ERROR)
{
return 4;
}
// }
//ShowMessage ( "Server: Waiting for a client to connect ...\n"); // Just to keep us up to date - ish
int len= sizeof (struct sockaddr);
sock_ER=accept(sock_ER,(sockaddr*)&escritorioRem, &len);
//
//do{
if( sock_ER<0){
return 5;
}
sendingCaps=true;
startSendCaps();
return 0;
}
Client:
int client(string serv, int puerto)
{
int error;
WSAData wsaData;
error = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (error == SOCKET_ERROR)
{
return 1;
}
// ShowMessage( "Client: WinSocket Loaded.\n");
if (sock == SOCKET_ERROR)
{
return 2;
}
// ShowMessage( "Client: Socket Opened Successfully!\n");
const char *server_name = serv.c_str(); // The server name we will connect to
struct hostent *host_entry; // Translates into something the computer can understand
host_entry = gethostbyname(server_name); // Gather out information
if (host_entry == NULL)
{
return 3;
}
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons((unsigned short) puerto);
server.sin_addr.s_addr = *(unsigned long*) host_entry->h_addr;
if(connect(ventanaCliente->sock, (sockaddr*)&server, sizeof(struct sockaddr))<0){
return 4;
}
receivingCaps=true;
strartReceiveCaps();
return 0;
}

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.