I have a simple class that starts a server and listens to clients and after they connect it starts a thread for them, my problem is that when I run the server it seems to be listening and when I try to connect using simple python code the server doesn't accept a socket.
Obviously I thought the problem is with the client connection but after trying to change to address from loopback to my local address I get the same result so I'm not sure what's causing this.
Server code:
Communicator::Communicator()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
throw std::runtime_error("Failed to startup WSA");
}
m_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_sock == INVALID_SOCKET)
{
throw std::runtime_error("Failed to create socket");
}
}
Communicator::~Communicator()
{
try
{
WSACleanup();
closesocket(m_sock);
}
catch (...) {}
}
void Communicator::bindAndListen()
{
SOCKADDR_IN sa;
sa.sin_port = Config::getConfig()["port"]; // 8080
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = INADDR_ANY;
if (bind(m_sock, (const SOCKADDR*) & sa, sizeof(sa)) == SOCKET_ERROR)
{
throw std::runtime_error("Failed to bind socket");
}
if (listen(m_sock, SOMAXCONN) == SOCKET_ERROR)
{
throw std::runtime_error("Failed to start listening");
}
std::cout << "Listening" << std::endl; // This gets printed
while (true)
{
SOCKET clientSock = accept(m_sock, NULL, NULL); // Nothing accepted, program stuck here
std::cout << "Connection" << std::endl;
if(clientSock == INVALID_SOCKET)
{
throw std::runtime_error("Invalid connection");
}
startThreadForNewClient(clientSock);
}
}
Testing python code:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
s.connect(('127.0.0.1', 8080))
s.send(b"h")
The only error I'm getting is [WinError 10061] No connection could be made because the target machine actively refused it on my client, the server is continuously listening.
My problem was that I forgot to put the port in htons, sorry for my rookie mistake.
void Communicator::bindAndListen()
{
SOCKADDR_IN sa;
sa.sin_port = htons(Config::getConfig()["port"]);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = INADDR_ANY;
if (bind(m_sock, (const SOCKADDR*) & sa, sizeof(sa)) == SOCKET_ERROR)
{
throw std::runtime_error("Failed to bind socket");
}
if (listen(m_sock, SOMAXCONN) == SOCKET_ERROR)
{
throw std::runtime_error("Failed to start listening");
}
std::cout << "Listening" << std::endl;
while (true)
{
SOCKET clientSock = accept(m_sock, NULL, NULL);
std::cout << "Connection" << std::endl;
if(clientSock == INVALID_SOCKET)
{
throw std::runtime_error("Invalid connection");
}
startThreadForNewClient(clientSock);
}
}
Related
I am sending UDP packets to Hercules for testing, and whenever I send data it hangs Hecrcules.
I am not sure if it is an issue with my code.
Please have a look at my code and if it has any issues, please let me know.
void UDPConnect::Connect(unsigned short local_port, const char* local_addr)
{
WSADATA wsa;
int err;
err = WSAStartup(MAKEWORD(2, 2), &wsa);
if (err != 0)
{
//std::cout << "Failed. Error Code : " << err << std::endl;
QMessageBox Msgbox;
Msgbox.setText("Udp Connection Failed.");
Msgbox.exec();
exit(EXIT_FAILURE);
}
//Create a socket
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
{
// err = WSAGetLastError();
// std::cout << "Could not create socket : " << err << std::endl;
QMessageBox Msgbox;
Msgbox.setText("Could not create socket :");
Msgbox.exec();
exit(EXIT_FAILURE);
}
//Prepare the sockaddr_in structure
struct sockaddr_in server = {};
server.sin_family = AF_INET;
server.sin_port = htons(local_port);
if (local_addr)
{
server.sin_addr.s_addr = inet_addr(local_addr);
if (server.sin_addr.s_addr == INADDR_NONE)
{
// std::cout << "Invalid local address specified" << std::endl;
QMessageBox Msgbox;
Msgbox.setText("Invalid local address specified.");
Msgbox.exec();
closesocket(s);
exit(EXIT_FAILURE);
}
}
else
server.sin_addr.s_addr = INADDR_ANY;
//Bind
if (::bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
// err = WSAGetLastError();
// std::cout << "Bind failed with error code : " << err << std::endl;
QMessageBox Msgbox;
Msgbox.setText("Bind failed.");
Msgbox.exec();
closesocket(s);
exit(EXIT_FAILURE);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int UDPConnect::SendPacket(byte *buffer, unsigned int buf_size, const char* remote_addr, unsigned short remote_port)
{
struct sockaddr_in si_other = {};
int send_len;
//Prepare the sockaddr_in structure
si_other.sin_family = AF_INET;
si_other.sin_addr.s_addr = inet_addr(remote_addr);
si_other.sin_port = htons(remote_port);
if ((send_len = sendto(s, (char*)buffer, buf_size, 0, (struct sockaddr *) &si_other, sizeof(si_other))) == SOCKET_ERROR)
{
}
return send_len;
}
When I use the boost library to send data, I have no problem.
bool UDPConnect::send_udp_message(const std::string& message, const std::string& destination_ip, const unsigned short port)
{
boost::asio::io_service io_service;
boost::asio::ip::udp::socket socket(io_service);
// Create the remote endpoint using the destination ip address and
// the target port number. This is not a broadcast
auto remote = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(destination_ip), port);
try {
// Open the socket, socket's destructor will
// automatically close it.
socket.open(boost::asio::ip::udp::v4());
// And send the string... (synchronous / blocking)
socket.send_to(boost::asio::buffer(message), remote);
}
catch (const boost::system::system_error& ex) {
// Exception thrown!
// Examine ex.code() and ex.what() to see what went wrong!
return false;
}
return true;
}
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 );
}
I am currently learning C++ and I am creating a library that handles sockets for both Windows and Linux platforms. I've got the Windows version working fine but the Linux version seems to not work as expected.
Below is the code that I have to create a socket:
bool LinuxSocket::createSocket(int family, int socketType, int port, int bufferLength)
{
BaseSocket::createsocket(port, bufferLength);
this->serverSocket = socket(family, socketType, 0);
if (this->serverSocket < 0)
{
bitsLibrary->writeToLog("Error opening socket", "LinuxSocket", "createSocket");
return false;
}
bzero((char *)&this->serv_addr, sizeof(this->serv_addr));
serv_addr.sin_family = family;
serv_addr.sin_addr.s_addr = INADDR_ANY;
//serv_addr.sin_port = htons(port);
serv_addr.sin_port = port;
return true;
}
Below is the code for binding and starting the port to listen:
bool LinuxSocket::bindAndStartListening()
{
stringstream logstream;
int result = bind(this->serverSocket, (struct sockaddr * )&serv_addr, sizeof(serv_addr));
if (result < 0)
{
logstream << "Failed to bind socket. Error: " << strerror(result);
this->bitsLibrary->writeToLog(logstream.str(), "LinuxSocket", "bindAndStartListening");
return false;
}
if (listen(this->serverSocket, this->socketPort) < 0)
{
this->bitsLibrary->writeToLog("Failed to start listening", "LinuxSocket", "bindAndStartListening");
return false;
}
logstream << "Socket " << this->socketPort << " has been successfully bound";
this->bitsLibrary->writeToLog(logstream.str(), "LinuxSocket", "bindAndStartListening");
return true;
}
Below is the code that accepts a client connection and returns the socket
int LinuxSocket::acceptClientAndReturnSocket(sockaddr_in *clientAddr)
{
socklen_t clilen = sizeof(clientAddr);
int clientSocket = accept(this->serverSocket, (struct sockaddr *)&clientAddr, &clilen);
if (clientSocket < 0)
{
this->bitsLibrary->writeToLog("Unable to accept client socket");
throw SocketException(strerror(clientSocket));
}
return clientSocket;
}
Below is how I am calling the methods
BitsLibrary bitsLibrary;
StaticSettings staticSettings(&bitsLibrary, "tunnel.conf");
LinuxSocket linuxSocket(&bitsLibrary);
linuxSocket.createSocket(AF_INET, SOCK_STREAM, 500, 20);
linuxSocket.bindAndStartListening();
sockaddr_in clientAddr;
int clientSocket = linuxSocket.acceptClientAndReturnSocket(&clientAddr);
When I run the program no errors seem to be returned and I log out Socket 500 has been successfully bound so it seems like it works, however when trying to connect I get a connection refused.
I've then run netstat -plna | grep 500 but this doesn't seem to return anything so it doesn't look like its actually binding the socket.
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;
}
back again (sorry)
I've created a socket C++ application, but it isn't working properly.
This is my first code:
void Network::Start()
{
this->socket = Env::GetSocket();
SOCKADDR_IN sInformation;
sInformation.sin_family = AF_INET;
sInformation.sin_addr.s_addr = INADDR_ANY;
sInformation.sin_port = htons(30000);
bind(this->socket, (SOCKADDR*) (&sInformation), sizeof(sInformation));
listen(this->socket, 10);
while (true)
{
this->DO();
}
}
And the DO function:
void Network::DO()
{
SOCKET s = SOCKET_ERROR;
sockaddr_in sock_addr;
accept(s, (sockaddr*) &sock_addr, NULL);
if (INVALID_SOCKET == s)
{
return;
}
else
{
cout << "Received connection from " << inet_ntoa(sock_addr.sin_addr);
}
}
What happens, always (even if I connect) the value s is INVALID_SOCKET. I connect via a .SWF but it doesn't accept my connection. What am I doing wrong?
You are not doing adequate error handling, and you are not using accept() correctly. Try this:
void Network::Start()
{
this->socket = Env::GetSocket();
if (this->socket == INVALID_SOCKET)
{
// error
return;
}
SOCKADDR_IN sInformation = {0};
sInformation.sin_family = AF_INET;
sInformation.sin_addr.s_addr = INADDR_ANY;
sInformation.sin_port = htons(30000);
if (bind(this->socket, (SOCKADDR*) &sInformation, sizeof(sInformation)) != 0)
{
// error
return;
}
if (listen(this->socket, 10) != 0)
{
// error
return;
}
while (true)
{
this->DO();
}
}
void Network::DO()
{
SOCKADDR_IN sock_addr = {0};
socklen_t sock_addr_len = sizeof(sock_addr);
SOCKET s = accept(this->socket, (SOCKADDR*) &sock_addr, &sock_addr_len);
if (INVALID_SOCKET == s)
{
return;
}
cout << "Received connection from " << inet_ntoa(sock_addr.sin_addr);
// use s as needed. Don't forget to call close(s) or closesocket(s)
// when finished, depending on your platform...
}
accept takes the listening socket as a parameter, and returns the newly connected socket;
socklen_t length = sizeof(sockaddr_in);
s = accept(this->socket, (sockaddr*) &sock_addr, &length);
EDIT: Just tested the program, with the socket created with AF_INET, SOCK_STREAM and sInformation cleared out;
bzero((char *) &sInformation, sizeof(sInformation));
...it seems to be running well on MacOS X and linux.