cant connect to server in local network - c++

I have 2 Computers. My Server is running on the Debian one while my Client is running on the Windows PC.
The IP of my Server is 192.168.2.113, the one of my Client is 192.168.2.122.
When I telnet 127.0.0.1 or 192.168.2.113 on the Server Machine there is no problem.
The Problem is that I cant connect to the Server from my Client.
I opened the port 50002 via iptables with the comment:
sudo iptables -A INPUT -p tcp --dport 50002 --jump ACCEPT
The main.cpp of my Server:
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char client_message[2000];
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 50002 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//accept connection from an incoming client
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
//Receive a message from client
while( (read_size = recv(client_sock , client_message , 2000 , 0)) > 0 )
{
//Send the message back to client
write(client_sock , client_message , strlen(client_message));
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
return 0;
}
Something strange i noticed is that I can connect to www.google.com in firefox but not in telnet (on my client pc):
telnet>o www.google.com 80
I only get 400-badrequest error
help is very appriciated.

Suggestions:
Step 1) establish that you can ping your server from windows. This way we eliminate potential network configuration issues. Make changes to your firewall if needed.
ping 192.168.2.113
Step 2) Ping from server to access windows. Windows firewall can prevent communication as well.
ping 192.168.2.112
Step 3) I compiled your server program and run om Debian server.
Your program works as expected.
First I connected with telnet on same server to test the program. All good
Step 4) I used telnet from Windows 10 to connect to your server. It connected as well, sending encoded data back.
Step 5) I used PuTTY telnet from Windows that worked good as expected.
Step 6) Conclusion that you have network configuration problem on your system that is not your program related. It can be firewall as well. start with step 1 and 2. Then if needed troubleshoot your network. Regards Bogdan.

Related

Uploading a file from Computer on a online Server

Hey guys I am trying to write a program which can upload files from my computer to a online server.. I have started with a socket programming client side.....
I have written a code which successfully makes a connection to a server and i can send a message to a server also and can get a reply from it...
Have a look..
#include<stdio.h>
#include<winsock2.h>
#include<bits/stdc++.h>
#include<strings.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
int main(int argc , char *argv[])
{
struct sockaddr_in server;
WSADATA wsa;
SOCKET s;
char *message , server_reply[2000];
int recv_size;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
printf("Initialised.\n");
if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
}
printf("Socket created.\n");
server.sin_addr.s_addr = inet_addr("172.217.24.238");
server.sin_family = AF_INET;
server.sin_port = htons(80);
//Connect to remote server
if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("connect error");
return 1;
}
puts("Connected");
//Send some data
message = "GET / HTTP/1.1\r\n\r\n";
if( send(s , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
puts("Data Send\n");
//Receive a reply from the server
if((recv_size = recv(s , server_reply , 2000 , 0)) == SOCKET_ERROR)
{
puts("recv failed");
}
puts("Reply received\n");
//Add a NULL terminating character to make it a proper string before printing
server_reply[recv_size] = '\0';
puts(server_reply);
return 0;
}
Please suggest me how can i modify this to upload a file from my computer to a server whose IP address and port number is known to me.....
PS: I am new to socket programming ....
Please help....
Actual:code which successfully makes a connection to a server and i can send a message to a server also and can get a reply from it...
Expected: Modify to upload some file on server whose ip address and port number is known...
You need to read a bit more from HTTP RFC about posting data to the server.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST
You can get the correct example to learn how to POST the content as the body of HTTP request to the server.

C++ Winsock UDP sendto succeeds but I don't see the data being sent

I am working with UDP sockets over an ethernet interface between my workstation (192.168.0.1) and my WinCE6 device (192.168.0.100).
From my workstation I can send UDP packets toward my WinCE device where I have a receiving socket set up and properly receiving data on port 9002; the device then properly echoes back data to my workstation.
I want my device to answer to my workstation on a specific port: 9001.
This is the server running into my device, it is the same as this but I modified the socket bind to the address of the specific interface and I changed the PORT define:
#define BUFLEN 512 //Max length of buffer
#define PORT 9002 //The port on which to listen for incoming data
void test_udp( void )
{
SOCKET s;
struct sockaddr_in server, si_other;
int slen , recv_len;
char buf[BUFLEN];
WSADATA wsa;
slen = sizeof(si_other) ;
//Initialise winsock
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
return;
}
//Create a socket
if((s = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
{
printf( "Could not create socket : %d" , WSAGetLastError());
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl( 0xC0A80064 );
server.sin_port = htons( PORT );
//Bind
if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
{
return;
}
//keep listening for data
while(1)
{
//clear the buffer by filling null, it might have previously received data
memset(buf,'\0', BUFLEN);
//try to receive some data, this is a blocking call
if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == SOCKET_ERROR)
{
return;
}
// *** CHANGE THE SEND PORT
si_other.sin_port = htons( 9001 );
//now reply the client with the same data
if (sendto(s, buf, recv_len, 0, (struct sockaddr*) &si_other, slen) == SOCKET_ERROR)
{
return;
}
}
closesocket(s);
WSACleanup();
return;
}
When I added the line below the // *** CHANGE THE SEND PORT comment to try to send the data back to port 9001, I am getting an appropriate return value for sendto which matches the number of bytes I expect to have been sent, but I don't see the data coming on my workstation (listening on 9001).
I have been banging my head against this and I cant see anything wrong. In the modified example, Any help would be greatly appreciated.
UPDATE: A firewall on my development PC was at fault. It allowed traffic back on the same port my PC was sending on, but blocked traffic on any other port. Resolving that allowed the the traffic to be sent without code changes. I had disabled the firewall previously, but did not realize that the OS had flagged the ethernet as a "public network", which still had the firewall enabled.
If, as you said, you are not getting a SOCKET_ERROR from the sendto and you are seeing an appropriate return value, this means that your OS was able to find a route toward the destination IP and was able to buffer your send request.
To change the send port it's ok if you want to answer to a different port with respect to the one from which you received data but note that this is not a typical case; the si_other struct in fact will contain the source address after the recvfrom and so the source port too. So keep your code as it is on your device side.
If you are not seeing data flowing to your workstation probably, in a simple networking context as your development environment, the problem is on the workstation: it is not receiving data.
I agree with #Daniel that you have to investigate with WireShark to see what's happening to packets.
Hope this helps

How to run a live server win winsock?

So I want to run a live server on my pc to connect and get info from someone else. I thought I can let the other person connect to my ip address on a port that is not used. So for example if my hypothetical ip address is 214.231.34.12 and port 50000 and I open te connection and give this information to someone, they can connect to it and send me information through TCP.
I thought I could use this code:
// TCPClient.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#define _WINSOCK_DEPRECATED_NO_WARNINGS
/*
Live Server on port 50000
*/
#include<io.h>
#include<stdio.h>
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
int main(int argc, char *argv[])
{
WSADATA wsa;
SOCKET s, new_socket;
struct sockaddr_in server, client;
int c;
char *message;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//Create a socket
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf("Could not create socket : %d", WSAGetLastError());
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
server.sin_addr.s_addr = inet_addr("214.231.34.12");
server.sin_family = AF_INET;
server.sin_port = htons(50000);
//Bind
if (bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
puts("Bind done");
//Listen to incoming connections
listen(s, 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while ((new_socket = accept(s, (struct sockaddr *)&client, &c)) != INVALID_SOCKET)
{
puts("Connection accepted");
//Reply to the client
message = "Hello Client , I have received your connection. But I have to go now, bye\n";
send(new_socket, message, strlen(message), 0);
}
if (new_socket == INVALID_SOCKET)
{
printf("accept failed with error code : %d", WSAGetLastError());
return 1;
}
closesocket(s);
WSACleanup();
return 0;
}
But it is failing at binding the connection. This whole TCP and winsocket stuff is totally new to me and I do not understand how I should approach this differently. I know this code is not receiving any information yet, it is just the connection that I try to get working at the moment. Is this not the right way to set this up?
The bind() fails with windows socket error 10049
There are plenty of obstacles for establish a TCP connection over internet:
internet itself: bad/unstable connection, dynamic ips, etc
ISP: maybe your ISP blocks some ports or ips
router: router firewall, NAT traversal problems, upnp, etc
OS: windows firewall, antivirus, port blocked/in use
YOUR APP: maybe a code mistake
Is a complete new world link to pcs over internet, the concept is the same, but implement it......
So it might be an answer, but maybe I have to use another port as datenwolf suggested.
I found that it is not possible to bind to my ISP's ipaddress. So I have forward the port I want to use and then connect to the ipaddress of my computer, as mentioned here:
connecting to an IP address instead of localhost?
I tried that, so I changed the ipaddress in code to:
//Prepare the sockaddr_in structure
server.sin_addr.s_addr = inet_addr("192.168.178.93");
server.sin_family = AF_INET;
server.sin_port = htons(50000);
And then when I connect to 214.231.34.12 and port 50000 with telnet, the connection works! I just wonder if this is a valid result?

C++ Reconnect TCP Server to Client after Client restart

I want to implement a 'flexible' TCP connection where I can randomly shutdown and restart both the Server and the Client. The other one should then automatically detect the shutdown and enter try to reconnect. I successfully implemented this s.t. I can shutdown and restart the server. The client discovers the shutdown (via recv(...) == 0) and then closes the connection (it therefore closes the sockets close(this->sockfd_) and close(this->newsockfd_)).
Unfortunately I am not able to get this working the other way around. I initialize the server (using the class constructor) the following way:
tcpServer::tcpServer(int _port) {
this->sockfd_ = -1;
this->port_ = _port;
this->connected_ = false;
if ((this->sockfd_ = socket(AF_INET, SOCK_STREAM, 0)) < 0)
this->dieWithError("ERROR opening Socket");
else
printf("-> Port %d: Socket opened\n", this->port_);
// get rid of "address already in use" error message
int yes = 1;
setsockopt(this->sockfd_, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
/* assign values to the fields of struct sockaddr_in */
bzero((char *) &this->serv_addr_, sizeof(this->serv_addr_));
this->serv_addr_.sin_family = AF_INET;
this->serv_addr_.sin_port = htons(this->port_);
this->serv_addr_.sin_addr.s_addr = INADDR_ANY;
/* bind the socket to an address */
if (bind(this->sockfd_, (struct sockaddr *) &this->serv_addr_, sizeof(this->serv_addr_)) < 0) {
printf("-> Port %d:", this->port_);
this->dieWithError("ERROR on binding");
}
printf("-> Binding successful. Start TCP client in new terminal\n");
fflush(stdout);
/* listen for connections and accept a connection */
listen(this->sockfd_, 5);
this->clilen_ = sizeof(this->cli_addr_);
if ((this->newsockfd_ = accept(this->sockfd_, (struct sockaddr *) &this->cli_addr_, &this->clilen_)) < 0)
this->dieWithError("Error on accept");
else {
printf("-> Connection established\n");
this->connected_ = true;
}
}
So once the server detects that the connection is closed, it enters a loop where it tries to reconnect using the following code:
void tcpServer::connect() {
if (this->sockfd_ == -1) {
/* create socket */
if ((this->sockfd_ = socket(AF_INET, SOCK_STREAM, 0)) < 0)
this->dieWithError("ERROR opening Socket");
else
printf("-> Port %d: Socket opened\n", this->port_);
// get rid of "address already in use" error message
int reuse_address = 1;
setsockopt(this->sockfd_, SOL_SOCKET, SO_REUSEADDR, &reuse_address, sizeof(int));
/* listen for connections and accept a connection */
listen(this->sockfd_, 5);
this->clilen_ = sizeof(this->cli_addr_);
if ((this->newsockfd_ = accept(this->sockfd_, (struct sockaddr *) &this->cli_addr_, &this->clilen_)) < 0)
this->dieWithError("Error on accept");
else {
printf("-> Connection established\n");
this->connected_ = true;
}
}
}
Some simple debugging output tells me that in the reconnect-mode, the server gets stuck in the
accept(this->sockfd_, (struct sockaddr *) &this->cli_addr_, &this->clilen_) call. Another observation I made is that the client does not shut down properly (via ctrl-c), i.e., it gets stuck in a loop somewhere and does not properly close the connection.
Since I am a total beginner with the TCP stuff, I would be very happy if someone could point me to the right direction. Thank you.

SOCKET connection problems in a service on Windows Server 2012

I inherited a C++/Windows project where we have an SNMP extension agent (loaded by SNMP service). Inside the agent, we are creating a simple TCP server to which our client applications connect and provide it with data for SNMP queries/traps etc. This all seems to work fine on Windows Server 2008. However, on Windows Server 2012, the client can no longer connect to the server running inside the agent (in SNMP service). The connect() fails with error 10013.
My server code looks something like this:
fd_set master_set;
fd_set readfds;
SOCKET listener;
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
{
OutputDebugStringA("WSAStartup failed\n");
return -1;
}
FD_ZERO(&master_set);
FD_ZERO(&readfds);
//----------------------
// Create a SOCKET for listening for
// incoming connection requests.
listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listener == INVALID_SOCKET) {
OutputDebugStringA("socket failed with error:\n");
return -1;
}
int reuse_addr = 1;
setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse_addr, sizeof(reuse_addr));
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
sockaddr_in service = { 0 };
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(27015);
if (bind(listener, (SOCKADDR *)& service, sizeof(service)) == SOCKET_ERROR)
{
printf("bind failed with error: %d \n", WSAGetLastError());
closesocket(listener);
return -1;
}
if (listen(listener, 5) == SOCKET_ERROR)
{
OutputDebugStringA("listen failed with error\n");
closesocket(listener);
return -1;
}
u_long NonBlock = 1;
if (ioctlsocket(listener, FIONBIO, &NonBlock) == SOCKET_ERROR)
{
OutputDebugStringA("ioctlsocket() failed with error\n");
return -1;
}
FD_SET(listener, &master_set);
timeval timeout;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
printf("Started Server on port %d\n", 27015);
for (;;)
{
readfds = master_set;
int ret = select(0, &readfds, NULL, NULL, &timeout);
if (ret == 0)
{
// Time out // Check if we need to shutdown
continue;
}
if (ret < 0)
{
printf("Error in Socket select\n");
return -1;
}
for (int i = 0; i < readfds.fd_count; i++)
{
SOCKET xfd = readfds.fd_array[i];
if (xfd == listener)
{
// New Connection.
SOCKET new_fd = HandleNewConnection(listener);
if (new_fd == -1)
{
printf("Error Accepting new connection");
continue;
}
FD_SET(new_fd, &master_set);
printf("Accepted new Connection\n");
continue;
}
else
{
if (!HandleIncomingData(xfd))
{
closesocket(xfd);
FD_CLR(xfd, &master_set);
continue;
}
}
}
}
SOCKET HandleNewConnection(SOCKET listener)
{
SOCKET newfd = accept(listener, (sockaddr*)NULL, (int*)NULL);
u_long NonBlock = 1;
ioctlsocket(newfd, FIONBIO, &NonBlock);
return newfd;
}
bool HandleIncomingData(SOCKET fd)
{
char buffer[16] = { 0 };
int recv_bytes = -1;
if ((recv_bytes = recv(fd, buffer, 16, 0)) <= 0)
{
printf("Connection Closed/ Error in Recieving");
return false;
}
printf("recieved %d bytes\n", recv_bytes);
return true;
}
The select continues to timeout every 3 seconds without any connection getting accepted.
Here's all that I have tried (none worked):
Tried to run the service in a specific user account.
The server is run in a separate thread, I provided a SECURITY_ATTRIBUTE with NULL DACL to see if it's a security problem.
Tried different ports.
Tried same server code in a separate normal application. The client can connect to this application.
Sample server application when launched from the agent, the client cannot connect to it.
Windows firewall is turned off and I don't have any anti virus software installed which would block such connections.
Checked connection from outside and observed in Wireshark that the TCP SYN packet does arrive but there's no response to it.
Observed in Process Explorer TCP/IP properties that the SNMP service does have a TCP socket listening on 127.0.0.1:27015.
For quick tests I am just doing telnet to port 27015.
Is there something obviously wrong with the server code which I am missing?
Is there some security restriction in Windows Server 2012 which don't allow a service to accept such TCP connections?
Any other hints, comments, inputs?
I solved the problem. The issue was due to Windows Service Hardening which did not allow any TCP communication from snmp service (and extensions). This is enforced even if the firewall is turned off.
https://support.microsoft.com/en-us/kb/2771908
I could solve it following these steps (found in http://www-01.ibm.com/support/docview.wss?uid=nas7ba16117761f1f93b86257f73000cff77)
Log on the system as Administrator and open Registry by issuing regedit in the command prompt.
Navigate to [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\Static\System].
Find the values which meet the following points:
a. “Name” string starts with “SNMP-”.
b. “Data” string contains “syswow64\snmp.exe”.
c. “Data” string contains “Action=Block”.
Change the “Action=Block” to “Action=Allow” of those entries.
Restart the “Windows Firewall” service by issuing net stop MPSSVC and net start MPSSVC .
Restart the “SNMP Service” service by using net stop SNMP and net start SNMP .