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

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

Related

Server problems

I try to make multithreaded server (C++, Visual Studio 2017), but have a problem: every time I start launch my .exe I get connected to port 52428 (while I even not start client). Why is heppening and how should I get rid of it.
Server:
#include <winsock2.h>
#include <thread>
#pragma comment(lib, "ws2_32.lib")
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if(err != 0)
return -1;
sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(8080);
local.sin_addr.s_addr = htonl(INADDR_ANY);
SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
bind(s, (struct sockaddr*)&local, sizeof(local));
cout << "Start server..." << endl;
int r = listen(s, 10000);
while(true)
{
sockaddr_in remote;
int j = sizeof(remote);
SOCKET newS = accept(s, (struct sockaddr*) &remote, &j);
if (newS == INVALID_SOCKET)
continue;
Socket sock = {newS, remote.sin_port, const_cast<const char*>(inet_ntoa(remote.sin_addr))}; // save socket, port and IP
cout << " Connect to port " << sock.port << endl;
thread thr(processing, ref(sock));
thr.join();
}
WSACleanup();
return 0;
}
Thank you for help.

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.

WINSOCK transmission in C++ loop

I am running a server client winsock software to transmit data in a loop from client to server. There is no problem in first transmission and it is perfect.
The second transmission and so on is corrupted and I don't know if it is about keep alive or something else. I spent 2 days trying to figure out.
Server side
#include"stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include<Windows.h>
#include <time.h>
#include"iostream"
#include"string"
#define MAXLINE 1000
int main()
{
// Initialize Winsock
WSADATA wsaData;
std::string message;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
printf("Server: Error at WSAStartup().\n");
// Create a SOCKET for listening for incoming connection requests.
SOCKET sockListen;
sockListen = socket(AF_INET, SOCK_STREAM, 0);
if (sockListen == INVALID_SOCKET)
{
printf("Server: Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 0;
}
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
struct sockaddr_in servAddr;
memset(&servAddr, 0, sizeof (servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(5000); /* daytime server */
if (bind(sockListen, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
{
printf("Server: bind() failed.\n");
closesocket(sockListen);
return 0;
}
// Listen for incoming connection requests on the created socket
if (listen(sockListen, 1) == SOCKET_ERROR)
printf("Server: listen(): Error listening on socket.\n");
printf("Server: I'm listening on socket, waiting for connection...\n");
SOCKET sockConn;
char recvbuff[MAXLINE];
while (1)
{
sockConn = accept(sockListen, NULL, NULL);
recv(sockConn, recvbuff, MAXLINE, 0);
message = recvbuff;
printf("%s \n", message);
std::cout << WSAGetLastError();
Sleep(100);
memset(recvbuff, 0, MAXLINE * (sizeof recvbuff[0]));
}
WSACleanup();
return 0;
}
Client side
#include"stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include<Windows.h>
#include <time.h>
#include"iostream"
#define MAXLINE 1000
int main()
{
// Initialize Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
printf("Client: Error at WSAStartup().\n");
// Create a SOCKET to connect to Server.
SOCKET sockClient;
sockClient = socket(AF_INET, SOCK_STREAM, 0);
if (sockClient == INVALID_SOCKET)
{
printf("Client: Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 0;
}
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
struct sockaddr_in servAddr;
char servHost[16];
memset(&servAddr, 0, sizeof (servAddr));
printf("Enter Host IP: ");
scanf("%s", servHost);
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(servHost);
servAddr.sin_port = htons(5000); /* daytime server */
// Connect to a server.
if (connect(sockClient, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
{
printf("Client: connect() - Failed to connect.\n");
WSACleanup();
return 0;
}
char buff[MAXLINE];
// Read data from server and display
connect(sockClient, (SOCKADDR*)&servAddr, sizeof(servAddr));
for (int x = 0; x < 100; x++)
{
sprintf(buff, "transmission number %d",x);
send(sockClient, buff, strlen(buff), 0);
memset(buff, 0, MAXLINE * (sizeof buff[0]));
Sleep(3000);
}
closesocket(sockClient);
WSACleanup();
closesocket(sockClient);
return 0;
}
the thing is i don't need to do the loop
sockConn = accept(sockListen, NULL, NULL);
just put it before the server loop solved and the problem solved even that am not sure why

Connecting to smtp server windows C++

I'm trying to create a client manager. I'have read some information about sockets. I'm doing my first steps and I've got my first problem.
This is my code:
#include <iostream>
#include <cstdio>
#include <winsock2.h>
#include <windows.h>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
const int VERSION_MAJOR = 1;
const int VERSION_MINOR = 1;
int main()
{
WSADATA WSData;
SOCKET sock;
struct sockaddr_in addr;
WSAStartup(MAKEWORD(VERSION_MAJOR, VERSION_MINOR), &WSData)
sock = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(25); // или любой другой порт...
hostent *server_adress = gethostbyname("smtp.gmail.com");
addr.sin_addr.s_addr = *((unsigned long *)server_adress->h_addr_list[0]);
int con = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
cout << "connect status " << con << '\n';
return 0;
}
connect() returns -1
why i can't connect? Where is mistake?
Please, help me
In the following line:
sock = socket(AF_INET, SOCK_STREAM, 0);
You do not specify a protocol. You should change it to
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
This is the kind of protocol you are going to want to establish with something such as a mailing service.

Winsock UDP filesending error 10040

This is my sending programm.
#pragma once
#pragma comment(lib,"Ws2_32.lib")
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
using namespace std;
int main()
{
WSAData wsaData;
WORD DllVersion = MAKEWORD(2,2);
int startup_RetVal = WSAStartup(DllVersion, &wsaData);
SOCKET sSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
SOCKADDR_IN addr;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_family = AF_INET;
addr.sin_port = htons(22222);
char buf[200000] = "AR*REF=";
int send_RetVal = sendto(sSocket, buf, 200000, NULL, (SOCKADDR*)&addr, sizeof(addr));
if(send_RetVal == SOCKET_ERROR)
{
cout <<" An error occured " << WSAGetLastError() << endl;
getchar();
}
return 0;
}
I get a WSAEMSGSIZE (10040) error.
The goal is to send a 100Kbytes file over udp. I was told that similar error on .NET was solved this way :
IPHostEntry^ IPHostTV;
IPEndPoint^ send_tv_ip;
Socket^ UDPSendTV;
int PortSendTV;
System::String^ IPSend;
send_tv_ip =
gcnew IPEndPoint(IPHostTV->AddressList[0], PortSendTV);
UDPSendTV =
gcnew Socket(send_tv_ip->Address->AddressFamily, SocketType::Dgram, ProtocolType::Udp);
//Increasing buffer and timeout
UDPSendTV->SendTimeout = 1000;
UDPSendTV->SendBufferSize = 100000;
UDPSendTV->SendTo(buff1, 0, size1, SocketFlags::None, send_tv_ip);
How do I modify my sockets so they work correctly?
The message size over UDP is limited by the protocol to ~64KB by the 16-bit message size field in the UDP header. There is no workaround.
(well, except for sending multiple messages per protocol unit).