How to run a live server win winsock? - c++

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?

Related

Sending Ethernet (UDP) Frames to other PCs

I am trying to send UDP frames from my laptop to another PC as a client-server application using C++. I am monitoring the ethernet port using WireShark and I do not see any information being sent from my laptop. Can someone help regarding this? Am I missing an important step?
/*
Simple udp client
*/
#include "stdafx.h"
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<stdio.h>
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#define SERVER "10.222.14.229"
#define BUFLEN 512
#define PORT 8888
int main(void)
{
struct sockaddr_in si_other;
int s, slen = sizeof(si_other);
char buf[BUFLEN];
char message[BUFLEN];
char message1[] = "Hello";
WSADATA wsa;
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//create socket
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
{
printf("socket() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
memset((char *)&si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);
while (1)
{
if (sendto(s, message1, strlen(message1), 0, (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
{
printf("sendto() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
memset(buf, '\0', BUFLEN);
puts(buf);
}
closesocket(s);
WSACleanup();
return 0;
}
There's nothing wrong with that code - it runs fine here (apart from the busy loop). Either:
the packets aren't going out on the wire, perhaps because there is no route to 10.222.14.229 (try pinging it), or
WireShark isn't functioning properly (can it see other traffic from your laptop? - it might have a filter set or something)
If you suspect WireShark, you could always try Microsoft Network Monitor.
The solution to this thread:
WireShark was missing the Pincap library when it was installed on Windows 10.
Installing the Pincap library solved the problem.

Trying to receive incoming UDP packets, empty buffer

I'm trying to read these incoming UDP packets using Wireshark:
I'm using the next code:
struct sockaddr_in si_other;
struct sockaddr_in remaddr; /* remote address */
int slen = sizeof(remaddr);
int s, recvlen;
char buf[BUFLEN];
char message[BUFLEN];
WSADATA wsa;
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//create socket
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == SOCKET_ERROR) //IPPROTO_UDP
{
printf("socket() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
//setup address structure
memset((char *)&si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);
if (bind(s, (struct sockaddr *)&si_other, sizeof(si_other)) < 0) {
perror("bind failed");
return 0;
}
u_long nMode = 1; // 1: NON-BLOCKING
if (ioctlsocket(s, FIONBIO, &nMode) == SOCKET_ERROR)
{
closesocket(s);
WSACleanup();
return 0;
}
//start communication
while (1)
{
printf("waiting on port %d\n", PORT);
if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Done");
puts(buf);
}
The address I'm binding is 192.168.1.1 and the port 1234.
And the given output by WSAGetLastError is an empty buffer error: 10035
I tried to disconnect firewall, antivirus...and I'm running the program as a administrator, and it didn't help.
Why is the buffer empty? I'm clearly seeing that there are packets coming, what could be blocking the incoming data to the socket?
the given output by WSAGetLastError() is an empty buffer error: 10035
No it isn't. 10035 is WSAEWOULDBLOCK. That means the operation would block in blocking mode, i.e. that no data was present to be received at the moment you called recvfrom().
The address I'm binding is 192.168.1.1
The IP 192.168.1.1 is shown as a gateway
These two statements are mutually inconsistent. If it's a gateway it's an external IP address, and if it's an external IP address you can't bind to it.
I tried INADDR_ANY and it didn't help
Not surprising. If you're not 192.168.1.1 you can't receive its messages. Unclear why you would think otherwise.
As #EJP mentioned 10035 is WSAEWOULDBLOCK, i.e., no data is ready. The cause of this is that the receiver is 192.168.1.1 which is your gateway's IP address, thus not a local IP. In this case you cannot receive the packets in a normal manner.
You can receive these packets, even though they are not meant for you, by using an UDP sniffer, e.g., using libpcap.
Thanks for the answers, they pointed me to the right direction. I 've got now the program working and I'm able to receive the incoming UDP packets.
The solution was to "sniff" these UDP packets, winsock allows that using the WSAIoctl function after bind, in my case adding the next code to the above program (after the bind function):
if (WSAIoctl(s, SIO_RCVALL, &j, sizeof(j), 0, 0, (LPDWORD)&si_other, 0, 0) == SOCKET_ERROR)
{
printf("WSAIoctl() failed.\n");
return 1;
}
I hope could help somebody else with similar issue.

c++ WINSOCK recvfrom no get data from network

i have problem because my server dont get UDP data. Ports on router are forwarded, data income to local-server network (it is visible on sniffer (3) ) but server dont receive it.
Server and server network screen
You can see 1 and 2 TCP packets correct income to server on connected sockets. But my client then send UDP data to server and data enter to local-server network (see that sniffer detect it on 3) but server dont take it.
Here is code of client:
struct sockaddr_in si_other;
int s, slen = sizeof(si_other);
char buf[10];
char message[10];
WSADATA wsa;
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//create socket
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
{
printf("socket() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
//setup address structure
memset((char *)&si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(14996);
si_other.sin_addr.S_un.S_addr = inet_addr(server ip);
memcpy(message, "cokolwiek", 8);
//send the message
if (sendto(s, message, strlen(message), 0, (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
{
printf("sendto() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
But its not problem with client. Here is server code but i think it is also correct:
SOCKET s;
struct sockaddr_in server, si_other;
int slen, recv_len;
char buf[10];
WSADATA wsa;
slen = sizeof(si_other);
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//Create a socket
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
printf("Could not create socket : %d", WSAGetLastError());
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(14996);
//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");
//blocking on it, waiting for data
if ((recv_len = recvfrom(s, buf, 10, 0, (struct sockaddr *) &si_other, &slen)) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
//print details of the client/peer and the data received
printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
printf("Data: %s\n", buf);
Some description that may help - main server loop is select() and when client ask for order, server send order back to client and starts proceeding command.
server:
while (1) {
select()
if (socket is in FD_SET)
get data, send it back and handleCommand()
}
handleCommand() {
tcp data exchange
wait for udp packet - it fail
}
client:
sendCommand()
//another receiving commands thread
while (recv) {
handle command
tcp data exchange
send udp data
}
Pls dont give me answears to do it in another wait. I need to punch hole for NAT Traversal. What problem is that? Another listener grabbing my data? But netstat -nop UDP -a didn't give information that something other is listening, and bind socket didn't failed. Also another important information That code work on the begining of program, i mean server receive data but later not.
Okey, so as ElderBug said
Are you sure you setup the UDP server socket before you send the data ? It's not clear in your question
Yep, it was my fault. The miniseconds decided that sending data on one machine was executed before setting up listener on server. Thank you for answer.
But i dont exactly understand the problem. Shouldn't that data income to receive buffer and wait for "grabbing" it by recvfrom function?

Winsock UDP broadcast packets not sent

I'm encountering a strange issue using winsock when multiple network adapters are active but then one is disconnected.
This is the basic scenario:
Wifi and Ethernet are active and connected
Launch app, send UDP broadcast and receive response
Unplug Ethernet, restart app and try to send again - Nothing is sent (Wireshark shows nothing, seems Windows is dropping them before they get to NIC?)
Disable the disconnected Ethernet adapter and try again - sends fine over Wifi and gets response.
Now this is a very specific scenario but I believe it's happening in other cases, this is just the only way I know to reproduce it every time.
The following is a code snippet of the UDP send, for this example assume dstAddrStr is 192.168.1.255
struct sockaddr_in sa_remote;
SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == INVALID_SOCKET) {
printf("Error creating socket: %ld\n", WSAGetLastError());
}
int enable = 1;
if ((setsockopt(sock,
SOL_SOCKET, SO_BROADCAST, (char*)&enable, sizeof(enable))) == -1) {
printf("Error enabling broadcasts: %ld\n", WSAGetLastError());
}
const MIB_IPADDRROW & row = iptbl->table[i];
uint32 ipAddr = ntohl(row.dwAddr);
uint32 netmask = ntohl(row.dwMask);
uint32 baddr = ipAddr & netmask;
if (row.dwBCastAddr) baddr |= ~netmask;
char dstAddrStr[32]; Inet_NtoA(baddr, dstAddrStr);
memset(&sa_remote, 0, sizeof(struct sockaddr_in));
sa_remote.sin_family = AF_INET;
sa_remote.sin_addr.s_addr = inet_addr(dstAddrStr);
sa_remote.sin_port = htons(_DST_PORT);
if (sendto(sock, dpString, strlen(dpString), 0, (struct sockaddr *)&sa_remote, sizeof(struct sockaddr_in)) < 0){
printf("UDP send error Error: %ld", WSAGetLastError());
break;
}

Trying to create UDP Server

I'm trying to create a UDP Server ,though without even client connecting to it, it recieves a connection...
(It writes in the console - New Connection a lot, so I guess it gets a new connection suddenly...)
#include <iostream>
#include <string>
#include <WinSock2.h>
#include <ws2tcpip.h>
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")
SOCKET ServerOn()
{
SOCKET ListenSocket;
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
{
exit(0);
}
// Create a SOCKET for listening for
// incoming connection requests.
ListenSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (ListenSocket == INVALID_SOCKET)
{
WSACleanup();
exit(1);
}
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("0.0.0.0");
service.sin_port = htons(2583);
if (bind(ListenSocket,(SOCKADDR *) & service, sizeof (service)) == SOCKET_ERROR)
{
closesocket(ListenSocket);
WSACleanup();
exit(2);
}
return ListenSocket;
}
int main()
{
SOCKET ListenSocket = ServerOn();
SOCKET ClientSocket;
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("10.0.0.2");
service.sin_port = htons(2583);
while(true)
{
if (ClientSocket = accept(ListenSocket, (SOCKADDR*)&service, NULL))
{
std::cout << "New Connection!" << std::endl;
}
}
}
Why is it getting connected without I ran anything? Maybe something else tries to connect to my server?
Thanks!
Two things: I don't think the IP address of your server can be 0.0.0.0, but instead 10.0.0.2; and also, UDP doesn't support the concept of 'accept'. There are just packets, and you can either bind a socket to a port, then receive packets from a specific IP (with recvfrom), or you can receive packets from anyone, with recv. The latter will be useful in case of a server. Note that you manually have to keep track of each connected client with a sockaddr_in structure.