C server socket accepts clients with no request - c++

I'll keep it simple.
Code:
#include "stdafx.h"
#include <winsock2.h>
#include <conio.h>
#include <iostream>
#include <stdio.h>
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsadata;
int error = WSAStartup(0x0202, &wsadata);
if(error) printf("WinSock error!");
SOCKET server;
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5657);
server_addr.sin_addr.s_addr = htonl (INADDR_ANY);
server = socket(AF_INET, SOCK_STREAM, 0);
if (server == INVALID_SOCKET) printf("INVALID SOCKET!");
error = bind(server, (LPSOCKADDR)&server_addr, sizeof(server_addr));
if(error) printf("Connect Error!");
listen(server, SOMAXCONN);
printf("SERVER ESTABLISHED! LISTENING...\n");
sockaddr_in client_addr;
SOCKET client;
client = accept(server, (struct sockaddr*)&client_addr, (int *)sizeof(client_addr));
if(client==INVALID_SOCKET) printf("INVALID SOCKET!\n");
printf("A CLIENT!");
closesocket(server);
WSACleanup();
getch();
return 0;
}
But what I get is:
SERVER ESTABLISHED! LISTENING...
INVALID SOCKET!
A CLIENT!
I've done sockets in C# and I guess the server is supposed to listen and wait for a client, and whenever a client requests for a connection, the server should accept it, but the server accepts a socket without waiting, and this accepted socket is invalid, too! Why does this happen and how can I solve it?

This:
(int *)sizeof(client_addr)
is wrong, you're casting the size to a pointer.
socklen_t client_addr_len = sizeof(client_addr);
client = accept(server, (struct sockaddr*)&client_addr, &client_addr_len);

(int *)sizeof(client_addr)
You're casting the client_addr size into an int*, so you have a pointer that points to an address which is equal to the size of your client_addr.
You need to do:
socklen_t clntAddrLen = sizeof(client_addr);
client = accept(server, (struct sockaddr*)&client_addr, &clntAddrLen);
This way is different because you have a variable of type socklen_t which holds the size of your client_addr. You're then getting a pointer (with &) that points to the memory address where that number is contained which is what you want.

The problem may be that accept will attempt to write to the last argument provided to it.
Change to:
int client_addr_size = sizeof(client_addr);
client = accept(server, (struct sockaddr*)&client_addr, &client_addr_size);
Checking the value of WSAGetLastError will provide the reason for failure.

Related

Why doesn't my UDP connection send messages even though there are no errors?

I took the UDP connection code from geeksforgeeks and made some changes as the code is problematic. I also took out some parts of it as I don't need my client to send an initial message. I just need the client to continuously receive 4 bytes of datagrams from the server.
The changes I made are mainly from:
Socket Programming Pointer Error
The problem I have now is that, as far as I know from my Python socket programming, a client would give an error if there is no port open to be connected, but my client seems to connect even though the server program is not running. However this is tcp that I am talking about. Is UDP supposed to act like this?
Second problem is that server sends a message even though there is no client and I assume this is the UDP process as there is no 3 way handshake and server assumes there is a client listening.
Basically it seems like server sends messages but client can't receive them even though both programs run without error.
The program can be in C or C++ as I am using cpp compiler and do not have a preference as long as it works.
server:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define MAXLINE 1024
// Driver code
int main() {
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from server";
struct sockaddr_in servaddr, cliaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
memset(&cliaddr, 0, sizeof(cliaddr));
// Filling server information
servaddr.sin_family = AF_INET; // IPv4
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);
// Bind the socket with the server address
if ( bind(sockfd, (const struct sockaddr *)&servaddr,
sizeof(servaddr)) < 0 )
{
perror("bind failed");
exit(EXIT_FAILURE);
}
int n;
socklen_t len;
len = sizeof(cliaddr); //len is value/resuslt
sendto(sockfd, (const char *)hello, strlen(hello),
0, (const struct sockaddr *) &cliaddr,
len);
printf("Hello message sent.\n");
return 0;
}
client:
// Client side implementation of UDP client-server model
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define MAXLINE 1024
// Driver code
int main() {
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from client";
struct sockaddr_in servaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = INADDR_ANY;
int n;
socklen_t len;
n = recvfrom(sockfd, (char *)buffer, MAXLINE,
MSG_WAITALL, (struct sockaddr *) &servaddr,
&len);
buffer[n] = '\0';
printf("Server : %s\n", buffer);
close(sockfd);
return 0;
}
Udp is very unreliable in such cases as it does not require ACK response packages from the server. Because of that, the program will not throw any errors even if the data isn't received. I would recommend using TCP instead or (if you are testing the code on a local network) check that the firewall ports your program uses are open both on client and server side.
You should know that UDP is not a reliable protocol: it just sends datagrams and never thinks about whether the other side has received it or not. If you want a reliable connection, you can choose TCP or a reliable protocol over UDP such as QUIC, kcp.
I think you should learn some basic network knowledge while progamming, such as from the books 《Unix Network Programming》and《TCP/IP Illustrated》, or you will meet many problems and don't know how to solve them.

How to Test and Run a Client Server Program in C++ using Eclipse

I am trying to get started with UDP and would like to test and debug some client server programs.
I am using an Eclipse IDE with cygwin64 as a compiler.
I have found some example client server programs from here: https://www.geeksforgeeks.org/udp-server-client-implementation-c/
I would like to be able to run the example to get me started on learning about UDP client servers.
The example code is as follows:
Server
// Server side implementation of UDP client-server model
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define MAXLINE 1024
// Driver code
int main() {
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from server";
struct sockaddr_in servaddr, cliaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
memset(&cliaddr, 0, sizeof(cliaddr));
// Filling server information
servaddr.sin_family = AF_INET; // IPv4
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);
// Bind the socket with the server address
if ( bind(sockfd, (const struct sockaddr *)&servaddr,
sizeof(servaddr)) < 0 )
{
perror("bind failed");
exit(EXIT_FAILURE);
}
int len, n;
n = recvfrom(sockfd, (char *)buffer, MAXLINE,
MSG_WAITALL, ( struct sockaddr *) &cliaddr,
&len);
buffer[n] = '\0';
printf("Client : %s\n", buffer);
sendto(sockfd, (const char *)hello, strlen(hello),
0, (const struct sockaddr *) &cliaddr,
len);
printf("Hello message sent.\n");
return 0;
}
Client
// Client side implementation of UDP client-server model
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define MAXLINE 1024
// Driver code
int main() {
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from client";
struct sockaddr_in servaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = INADDR_ANY;
int n, len;
sendto(sockfd, (const char *)hello, strlen(hello),
MSG_CONFIRM, (const struct sockaddr *) &servaddr,
sizeof(servaddr));
printf("Hello message sent.\n");
n = recvfrom(sockfd, (char *)buffer, MAXLINE,
MSG_WAITALL, (struct sockaddr *) &servaddr,
&len);
buffer[n] = '\0';
printf("Server : %s\n", buffer);
close(sockfd);
return 0;
}
I have tried opening up two different eclipse workbenches and running both the codes, but it is not running as expected and it is saying that the messages have been sent but I have not been able to receive them on the client or server.
I definitely would like to stick with c/c++ and try to get this working in eclipse if it's possible.
If anyone has any advice on how I can be able to see some results or anything that could get me started with this, it would be much appreciated. Thank you!
Problem
You have not set the address of the server correctly in the client code.
servaddr.sin_addr.s_addr = INADDR_ANY;
is meaningless when sending (Why would you want to send to any available address? You want to send to the server.) and is rejected by sendto. You would have seen this if you'd checked the return value. Always check the return value, even for UDP communications. Sure there are a million reasons why a packet won't arrive with UDP that you can't detect at the time of sendto, but it's good to know that the network stack actually accepted the message even if a grue subsequently devours the packet in one of the dark corners of the Internet. A sending error you can do something about, like perror and then fix the code accordingly. A grue, not so much. You'll have to make a protocol robust enough to retransmit or otherwise survive the loss of the packet.
Solution
Get the server's address structure with getaddrinfo.
Replace
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = INADDR_ANY;
with something more like
struct addrinfo hints;
struct addrinfo *hostlist;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = 0;
hints.ai_protocol = IPPROTO_UDP;
if (getaddrinfo("Server Name or Address Goes Here",
PORT, // this needs to be a char *, not an integer
&hints,
&hostlist))
{
// handle error
exit(EXIT_FAILURE);
}
PORT in this case needs to be a char *, so instead of
#define PORT 8080
use
constexpr char const * PORT = "8080";
You can leave out the constexpr if your compiler is old and doesn't support it.
Then when you go to send, iterate through the hostlist until you find a host that responds. Since you've probably narrowed the servers down to exactly one candidate, this is probably overkill, but you might as well get into practice doing things right. The alternative sucks when systems start getting complicated.
struct addrinfo *curhost;
for (curhost = hostlist; curhost != NULL; curhost = curhost->ai_next)
{
int rval = sendto(sockfd,
(const char *) hello,
strlen(hello),
0,
curhost->ai_addr,
curhost->ai_addrlen);
if (rval> 0) // always check return codes. Programmers are lazy.
// They wouldn't have gone to the effort of putting
// it there if it wasn't important.
{
if server responds
do protocol stuff to complete transaction
break;
}
}
freeaddrinfo(hostlist); // thou shalt not leak resources.
if (curhost == nullptr)
{
notify user that no server was willing to talk
}
Documentation for getaddrinfo.

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.

WSAGetLastError returns WSAENOTSOCK - Cause?

I have something like this in my code
WSADATA wsadata;
int error = WSAStartup(0x0202, &wsadata);
SOCKADDR_IN target; //Socket address information
target.sin_family = AF_INET; // address family Internet
target.sin_port = htons (5005);
target.sin_addr.s_addr = inet_addr ("127.0.0.1");
clntSocket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); //Create socket
if (::connect(clntSocket, (SOCKADDR *)&target, sizeof(target)) == SOCKET_ERROR)
{
//Could not connect
__debugbreak();
}
else
{
//Connected - Now receive data
do
{
char my_stream[800];
iResult = recv(clntSocket,my_stream,sizeof(my_stream),0);
if(iResult<0)
{
int a = WSAGetLastError();
//Receives 10038 - WSAENOTSOCK
}
} while( iResult > 0 );
}
And I would sometimes (occasionally) get 10038. Which states that
Socket operation on nonsocket.
An operation was attempted on something that is not a socket. Either the socket handle parameter did not reference a valid socket,or for select, a member of an fd_set was not valid.
Am I doing something wrong while setting up the socket ? Any suggestions on how to fix the problem ?
Either:
You never opened the socket.
You have corrupted the handle value.
You have closed the socket and then continued to use it.

Socket program Python vs C++ (Winsock)

I have python program which works perfectly for internet chatting. But program built on similar sockets in C++ do not work over internet.
Python program
import thread
import socket
class p2p:
def __init__(self):
socket.setdefaulttimeout(50)
self.port = 3000
#Destination IP HERE
self.peerId = '59.95.18.156'
#declaring sender socket
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM )
self.socket.bind(('', self.port))
self.socket.settimeout(50)
#starting thread for reception
thread.start_new_thread(self.receiveData, ())
while 1:
data=raw_input('>')
#print 'sending...'+data
self.sendData(data)
def receiveData(self):
while 1:
data,address=self.socket.recvfrom(1024)
print data
def sendData(self,data):
self.socket.sendto(data, (self.peerId,self.port))
if __name__=='__main__':
print 'Started......'
p2p()
I want to built similar functionality in c++. I took server and client programs from MSDN. But they are working only on localhost not over internet ..
they are as follows...
Sender
#include <stdio.h>
#include "winsock2.h"
void main() {
WSADATA wsaData;
SOCKET SendSocket;
sockaddr_in RecvAddr;
int Port = 3000;
char SendBuf[3]={'a','2','\0'};
int BufLen = 3;
//---------------------------------------------
// Initialize Winsock
WSAStartup(MAKEWORD(2,2), &wsaData);
//---------------------------------------------
// Create a socket for sending data
SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
//---------------------------------------------
// Set up the RecvAddr structure with the IP address of
// the receiver (in this example case "123.456.789.1")
// and the specified port number.
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.s_addr = inet_addr("59.95.18.156");
//---------------------------------------------
// Send a datagram to the receiver
printf("Sending a datagram to the receiver...\n");
sendto(SendSocket,
SendBuf,
BufLen,
0,
(SOCKADDR *) &RecvAddr,
sizeof(RecvAddr));
//---------------------------------------------
// When the application is finished sending, close the socket.
printf("Finished sending. Closing socket.\n");
closesocket(SendSocket);
//---------------------------------------------
// Clean up and quit.
printf("Exiting.\n");
WSACleanup();
return;
}
Receiver
#include <stdio.h>
#include "winsock2.h"
#include<iostream>
using namespace std;
void main() {
WSADATA wsaData;
SOCKET RecvSocket;
sockaddr_in RecvAddr;
int Port = 3000;
char RecvBuf[3];
int BufLen = 3;
sockaddr_in SenderAddr;
int SenderAddrSize = sizeof(SenderAddr);
//-----------------------------------------------
// Initialize Winsock
WSAStartup(MAKEWORD(2,2), &wsaData);
//-----------------------------------------------
// Create a receiver socket to receive datagrams
RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
//-----------------------------------------------
// Bind the socket to any address and the specified port.
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(RecvSocket, (SOCKADDR *) &RecvAddr, sizeof(RecvAddr));
//-----------------------------------------------
// Call the recvfrom function to receive datagrams
// on the bound socket.
printf("Receiving datagrams...\n");
while(true){
recvfrom(RecvSocket,
RecvBuf,
BufLen,
0,
(SOCKADDR *)&SenderAddr,
&SenderAddrSize);
cout<<RecvBuf;
}
//-----------------------------------------------
// Close the socket when finished receiving datagrams
printf("Finished receiving. Closing socket.\n");
closesocket(RecvSocket);
//-----------------------------------------------
// Clean up and exit.
printf("Exiting.\n");
WSACleanup();
return;
}
Thank you very much for any help ..
Sorry for too much code in the question.
Per the docs, sendto returns a number that's >0 (number of bytes sent) for success, <0 for failure, and in the latter case you use WSAGetLastError for more information. So try saving the sendto result, printing it (as well as the size of the data you're trying to send), and in case of error print the last-error code too. What do you see then?