TCP connection fails - c++

I wrote server and client code client can connect with server normally but only on local address i don't know how to connect over internet
int main()
{
struct addrinfo host_info;
struct addrinfo * host_list;
struct sockaddr sa;
struct sockaddr_in ip4addr;
memset(&host_info, 0, sizeof host_info);
host_info.ai_family = AF_INET; // IP version not specified. Can be both.
host_info.ai_socktype = SOCK_STREAM;
getaddrinfo(NULL, "5555", &host_info, &host_list);
int s;
s=socket(host_list->ai_family,host_list->ai_socktype,host_list->ai_protocol);
if(s==-1) printf("error\n");
int status = connect(s, host_list->ai_addr, host_list->ai_addrlen);
if (status == -1) printf("connect error\n");
char *message="Hi there!";
send(s, message, 10, 0);
return 0;
}
I tried to change NULL in getaddrinfo to ip address but it always fail to connect

Which TCP/IP address are you trying to connect to, over the internet?
getaddrinfo() should have an IP address of some sort, or it won't know where to connect. It's like trying to send a letter in the mail without an address on it.
Furthermore, there are a LOT of reasons you might not be able to connect. Your firewall could be blocking something... there could be a firewall on the other end that's blocking something... AV software could even be detecting a connection that it thinks is "weird," and blocking it... the IP address could be wrong.
It'd be helpful for you to talk about the troubleshooting that you've done and what you're seeing.

Related

cannot connect to my winsock server from another computer using my IP address

i am working on a chat.
i can start my server and client on the same computer using the 127.0.0.1 ip address and can talk fine, but if I try using my own IP address in the client to connect to the server, it does not connect. If someone else also tries to do it, it doesn't work
i have portforwarded in my router like this:
external host: my ip
internal host: my internal ip i got with ipconfig (192.168.1.4)
internal port: 54444
external port: 54444
even then, I think I should still be able to connect to my IP address without a portforward since the server is hosted on 127.0.0.1/localhost, right?
this is my client code:
WSADATA wsa;
if (!WSAStartup(MAKEWORD(2, 2), &wsa))
{
printf("started server\n");
SOCKET listen_sock = socket(AF_INET, SOCK_STREAM, 0);
if (listen_sock)
{
printf("created listen socket\n");
sockaddr_in addr;
addr.sin_family = AF_INET;
inet_pton(AF_INET, "92.83.235.216", &addr.sin_addr);
addr.sin_port = htons(54444);
if (!connect(listen_sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)))
{
printf("connected to server\n");
char buffer[2048];
char input[2048];
for(;;)
{
printf("message: ");
scanf_s("%s", input);
if (send(listen_sock, input, strlen(input) + 1, 0))
{
printf("\nsent message \"%s\"", input);
}
memset(input, 0, sizeof(input));
printf("\n");
}
}
}
}
printf("%d\n", WSAGetLastError());
WSACleanup();
it stops after it shows "creating listen socket", right at the connect() call
Any ideas?
EDIT: server code is very jumbled because of me making it into a class to make it easier to use + adding a thread to handle multiple connections, but like I said it does work internall
only thing different in the server code besides the listen and accept calls is these rules i added:
char opt_val = 1;
setsockopt(this->m_listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof(opt_val));
setsockopt(this->m_listen_sock, IPPROTO_TCP, TCP_NODELAY, &opt_val, sizeof(opt_val));
What you're describing sounds like your SYN packets are being dropped (SYN... no SYN/ACK or RST). You can use wireshark to see what is happening with the actual tcp connection (filter on port).
You might want to eliminate the server as a source of error by listening on localhost and connecting that way. You can verify it is listening on the correct address and port using netstat.
Otherwise, it would help if you posted your server code.

Does the code in a C++ winsock 2 application have to change when using a global IP address?

My code is based on the book "Network Programming for Microsoft Windows Second Edition", which can be found online as a PDF.
My code for the server application is:
#include <iostream>
#include <winsock2.h>
int main(void)
{
WSADATA wsaData;
SOCKET ReceivingSocket;
SOCKADDR_IN ReceiverAddr;
int Port = 5150;
char buffer;
SOCKADDR_IN SenderAddr;
int SenderAddrSize = sizeof(SenderAddr);
WSAStartup(MAKEWORD(2,2), &wsaData);
ReceivingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
ReceiverAddr.sin_family = AF_INET;
ReceiverAddr.sin_port = htons(Port);
ReceiverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(ReceivingSocket, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr));
recvfrom(ReceivingSocket, &buffer, 1, 0, (SOCKADDR *)&SenderAddr, &SenderAddrSize);
std::cout << buffer << std::endl;
buffer = 'b';
sendto(ReceivingSocket, &buffer, 1, 0, (SOCKADDR*)&SenderAddr, SenderAddrSize);
std::cin.get();
closesocket(ReceivingSocket);
WSACleanup();
}
And for the client application is:
#include <winsock2.h>
#include <iostream>
int main()
{
WSADATA wsaData;
SOCKET SendingSocket;
SOCKADDR_IN ReceiverAddr;
SOCKADDR_IN ex;
int Port = 5150;
char buffer = 'a';
WSAStartup(MAKEWORD(2,2), &wsaData);
SendingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
ReceiverAddr.sin_family = AF_INET;
ReceiverAddr.sin_port = htons(Port);
ReceiverAddr.sin_addr.s_addr = inet_addr("-->insert ip here<--");
sendto(SendingSocket, &buffer, 1, 0, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr));
int len = sizeof (ex);
recvfrom(SendingSocket, &buffer, 1, 0, (SOCKADDR*)&ex, &len);
std::cout << buffer << std::endl;
std::cin.get();
closesocket(SendingSocket);
WSACleanup();
}
When I insert a local IP, the code works perfectly fine - the applications detect each other and exchange buffers. But when I insert my global IP, the applications don't detect each other. Is it a problem with the code, or something I have to change when using a global IP, or something wrong with my network settings?
To clarify:
When I said about "inserting IP address", I meant writing it instead of "-->insert ip here<--".
By local IP, I meant my computer's local IP address, checked in the console using the ipconfig command.
By global IP, I meant the global IP of my router, which I checked on myglobalip.com, and I forwarded port 5150 to my local IP address.
This might be a bit off topic, but if it's something wrong with network settings, I would appreciate if you could give a link to a good tutorial because I couldn't find one that worked.
Nice code. Nice and simple. All I had to do was cut and paste (and add #pragma comment (lib, "ws2_32.lib")).
Are the client and the server both running on your LAN? If so, my tests indicate that they won't be able to talk to each other via your router's external IP address. This is because the router doesn't loop back packets sent out through its ADSL / VDSL port (why would it?) so they just disappear into the ether. I tried enabling both the DMZ and port forwarding on my router (at minimum, you need one or the other) but no dice, which was what I was expecting.
So to test this, you will need the help of a friend with a router of his own. Let's suppose he is running the client. You will then need to put your server machine into your router's DMZ or (better, because it's safer) set up port forwarding for UDP port 5150 on your router to the server machine. In either case, give that machine a static IP address on your LAN else it might move. Then you have a chance of seeing this work.
Our friends over at superuser have this to say about sending UDP packets via [routers implementing] NAT (which is what you will have there) and getting an answer back:
IF Machine A sends [a UDP] frame from the same source port as the destination port ("Port N"), and IF the NAT is able to preserve that source port (i.e. it's configured to preserve source ports when possible, and that source port is not in use), THEN you can expect a reply to "Port N" to get back to Machine A.
But the problem currently is that nothing is listening. Certainly not your server program.

Display HTTP Request sent to my server using c++

I am currently learning about the internet. I am trying to set up a simple proxy server that just forwards a request from the server side to its client side. Im currently following this tutorial. This is how far I have gotten:
#define MYPORT "3490" // the port users will be connecting to
#define BACKLOG 10 // how many pending connections queue will hold
int main(int argc, const char* argv[]) {
struct addrinfo hints;
struct addrinfo *res;
int sockIn;
int sockOut;
memset(&hints, 0, sizeof hints); // make sure its empty
hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
hints.ai_socktype = SOCK_STREAM; // what kind of socket
hints.ai_flags = AI_PASSIVE; // fill in my IP for me
//listens on the hosts ip address:
getaddrinfo(NULL, MYPORT, &hints, &res);
// make a socket, bind it, and listen on it:
sockIn = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
bind(sockIn, res->ai_addr, res->ai_addrlen);
listen(sockIn, BACKLOG);
freeaddrinfo(res); // free the linked-list
struct sockaddr_storage their_addr;
socklen_t addr_size;
char buf[512];
while(1) {
addr_size = sizeof their_addr;
struct sockaddr *addr = (struct sockaddr *)&their_addr;
sockOut = accept(sockIn, addr, &addr_size);
recv(sockOut, buf, sizeof buf, 0);
for (auto ch : buf) {
cout << ch;
}
close(sockOut);
}
}
Right now im just displaying "hi" on every page I visit.
Before I implement the client side of the proxy id like to instead display the HTTP Get Request that my browser sends to the server side of the proxy. My issue is that I dont know how to retrieve it. The guide I'm using is not adressering this.
Edit: I added a recv call that is suppose to read everything from the socket in to a buffer. Unfortunately it does not cout anything
download and install wireshark (packet sniffer), or else Fiddler Fiddler(HTTP proxy). You will easily be able to inspect HTTP traffic. I recommend you start with fiddler. Install on computer where your browser is located.

Socket being set up without errors, but no connection

I am trying to learn how to use TCP/IP via 2 Linux machines, both of which have functioning internet connections. I tried setting up a server and a client, but I'm not getting a connection, despite not getting any errors during setup.
Server code:
int serverSocketFd,clientSocketFd,clientLength,numberOfBytes;
static struct sockaddr_in server_address, clint address;
char buf[256];
serverSocketFd = socket(AF_INET,SOCK_STREAM,0);
if(serverSocketFd<0){error("socket() call Failed");}
//Clears the allocated space of the sockaddr_in struct before configuration
bzero((char *)&server_address, sizeof(server_address));
server_address.sin_family = AF_INET;
//inet_aton should take an IP address in string format and convert it to the proper format for the struct. Returns nonzero for error
if(!inet_aton("XXX.XXX.XXX.XXX",&(server_address.sin_addr))){error("inet_aton() Failed");}
//Picked a random port number for this test
server_address.sin_port = htons(34567);
//Quick check that I have the expected settings
inet_ntop(AF_INET,&server_address.sin_addr,buf,255);
printf("Listening on %s:%d\n",buf,server_address.sin_port);
if(bind(serverSocketFd,(struct sockaddr *)&server_address,sizeof(server_address)) <0){error("bind() call Failed");}
//At this point, Socket should be prepped to start listening, and waits here until another program makes contact
printf("Waiting on client...\n");
listen(serverSocketFd,5);
//If a client program makes a connection, the 'clinetSocketFd' represents it
clientLength = sizeof(client_address);
clientSocketFd = accept(serverSocektFd, (struct sockaddr *)&clinet_address, (socklen_t *)&clientLength);
if(clientSocketFd < 0){error("accept() call returned invalid");}
printf("CONNECTION ACCEPTED\n");
//Now that a connection is established, wait for a request from client
bzero(buf,256);
numberOfBytes = read(clientSocketFd,buf,255);
if(numberOfBytes<0){error("read() call Failed");}
printf("MESSAGE RECEIVED: %s\n",buf);
numberOfBytes = write(clientSocketFd,"ACKNOWLEDGED",strlen("ACKNOWLEDGED"));
return numberOfBytes;
I expect the output to be a message printing my IP address and port, then a wait message, then a message announcing a connection, then a message announcing a request from the client, and the incoming text.
Client code:
static struct sockaddr_in server_address;
char buf[256];
int numberOfBytes,e;
clientSocketFd = socket(AF_INET,SOCK_STREAM,0);
if(clientSocketFd<0){error("socket() call Failed");}
//Clears allocated space of the sockaddr_in struct before configuration
bzero((char *)&server_address, sizeof(server_address));
server_address.sin_family = AF_INET;
//The IP address being put in here is the same as the one put in the server code, the IP address of the host machine.
if(!inet_aton("XXX.XXX.XXX.XXX",&(server_address.sin_addr))){error("inet_aton() Failed");}
server_address.sin_port = htons(34567);
//Same check as server code, look at the target IP and port
inet_ntop(AF_INET, &server_address.sin_addr,buf,255);
printf("Connecting to %s:%d\n",buf,server_address.sin_port);
//As client, we connect the socketFd for the CLIENT to the address struct of the SERVER
e = connect(clientSocketFd,(struct sockaddr *)&server_address,sizeof(server_address));
if(e<0){error("connect() call Failed");printf("Error code %d\n",e);}
//Connection has now been established and can be referenced through clientSocketFd
printf("CONNECTION ESTABLISHED\n");
//Now send a generic message
numberOfBytes = write(clientSocketFd,"TESTMESSAGE",strlen(message));
if(numberOfBytes<0){error("write() call Failed");}
bzero(buf,256);
numberOfBytes = read(clientSocketFd,buf,255);
if(numberOfBytes<0){error("read() call Failed");}
printf("%s\n",buf);
return 0;
I expect the output to be roughly the same, print the target IP and port, acknowledgement messages, and then the received acknowledge.
What I end up seeing, on both machines, is up to the listen/connect stage.
I see the "Listening on/Connecting to XXX.XXX.XXX.XXX:34567", which matches up with the IP address on the machine running the server code. Then it times out. errno is set to ECONNREFUSED.
The connection is never made, but no error comes up before this point, so it doesn't seem like anything went wrong while configuring the sockets.
Can someone explain what is problem is with this code?

Linux UDP Server unreachable from Window 7

I have the following configuration for my experiment.
Wifi(Belkin) router connected to Internet.
Laptop with Windows 7 OS
Laptop with Ubuntu OS.
Experiment: When I connect both of my laptop to Wifi router it assigns DHCP IPs 192.168.2.2 to Linux & 192.168.2.3 to Win 7. Both of them can browse internet.
I start a UDP server on my Linux machine with the following code.
int main(int argc, char *argv[]) {
int sd, rc, n, cliLen, flags;
struct sockaddr_in cliAddr, servAddr;
char msg[MAX_MSG];
//Create a socket
sd=socket(AF_INET, SOCK_DGRAM, 0);
if(sd<0){ printf("%s: cannot open socket \n",argv[0]); exit(1); }
//Bind now to a port
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr("192.168.2.2");
servAddr.sin_port = htons(9999);
rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr));
if(rc<0) {printf("%s: cannot bind port number %d \n", argv[0], 9999);exit(1);}
//We are done ... Notify User
printf("%s: waiting for data on port UDP %u\n",argv[0],LOCAL_SERVER_PORT);
//Server's Infinite Loop
while(1)
{
memset(msg,0x0,MAX_MSG);//Sanity
/* receive message */
cliLen = sizeof(cliAddr);
n = recvfrom(sd, msg, MAX_MSG, flags,(struct sockaddr *) &cliAddr, (socklen_t * )&cliLen);
if(n<0){printf("%s: cannot receive data \n",argv[0]);continue;}
//Received message
printf("%s: from %s:UDP%u : %s \n", argv[0],inet_ntoa(cliAddr.sin_addr),ntohs(cliAddr.sin_port),msg);
sleep(1);
//Sending back the data thus received
sendto(sd,msg,n,flags,(struct sockaddr *)&cliAddr,cliLen);
}//while
return 0;
}
This code work well & I can receive the packet to the server when some local client on the Linux machine tries to contact my server.
PROBLEM : When I make the same client in Android AVD present in my windows 7 system I am unable to reach my server.
I thought may be that's firewall issue, so I removed the firewall & added by pass custom rules to the IP "192.168.2.2" as given in the following link. http://www.brighthub.com/computing/windows-platform/articles/40014.aspx#
But it did not work. I thought that first I should try with raw java first then with AVD.
Hence, I created a UDP client with Java code still I was not able to connect to server.
Then I thought let's try with raw C++ so that I would come to know exactly what is the problem. Following is the Visual Studio code which I implemented for the same.
#define PORT_NUM 9999 // Port number used
#define IP_ADDR "192.168.2.2" // IP address of server1
#define BUFFER_SIZE 4096
void main(void){
WORD wVersionRequested = MAKEWORD(2,2); // Stuff for WSA functions
WSADATA wsaData; // Stuff for WSA functions
int client_s; // Client socket descriptor
struct sockaddr_in server_addr; // Server Internet address
int addr_len; // Internet address length
char out_buf[BUFFER_SIZE]; // Output buffer for data
char in_buf[BUFFER_SIZE]; // Input buffer for data
int retcode; // Return code
// This stuff initializes winsock
WSAStartup(wVersionRequested, &wsaData);
client_s = socket(AF_INET, SOCK_DGRAM, 0);
if (client_s < 0){ printf("*** ERROR - socket() failed \n"); exit(-1);}
server_addr.sin_family = AF_INET; // Address family to use
server_addr.sin_port = htons(PORT_NUM); // Port num to use
server_addr.sin_addr.s_addr = inet_addr(IP_ADDR); // IP address to use
strcpy(out_buf, "Test message from CLIENT to SERVER");
retcode = sendto(client_s, out_buf, (strlen(out_buf) + 1), 0,(struct sockaddr *)&server_addr, sizeof(server_addr));
if (retcode < 0){printf("*** ERROR - sendto() failed \n");exit(-1);}
addr_len = sizeof(server_addr);
retcode = recvfrom(client_s, in_buf, sizeof(in_buf), 0,(struct sockaddr *)&server_addr, &addr_len);
if (retcode < 0){printf("*** ERROR - recvfrom() failed \n");exit(-1);}
printf("Received from server: %s \n", in_buf);
retcode = closesocket(client_s);
if (retcode < 0){ printf("*** ERROR - closesocket() failed \n");exit(-1);}
WSACleanup();
}
But it gives me error of destination unreachable.
To find out exactly what is going on at the packet level, I installed "Wireshark", on my ubuntu machine.
My observation is... whenever my windows client executes I get a ICMP message 3 times on the Wireshark having the type 3 message. The detailed analysis of the packet showed that the port is unreachable.
Kindly help me to find out what I am missing here :(.
Have you tried disabling the firewall on the linux machine, or adding an exception for the port you are using?
sudo ufw disable
or use the following to show your iptables firewall rules:
sudo iptables -L
Check the connection between the two machines
ICMP: ping win->lin and back
TCP: connect SSH, Samba, or even browser if you can run some web server
UDP: use nc (netcat) utility to test UDP/TCP connection between two machines
If one of these does not work, look for the problem :
Shut down the firewalls on both computers and on the wireless AP, run sniffers on Win and on Lin machines.
If the connection is ok, the you know you have a bug in your program. Start debugging each end against something working - i.e. nc.