socket programming c++ windows, can't see received message from server [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am writing a network client-server program:
Server side:
#include "stdafx.h"
#include <winsock.h>
#include <stdio.h>
#include<stdlib.h>
#define PROTOPORT 5193
#define QLEN 6
#define BUFFERSIZE 512
void ErrorHandler(char *errorMessage)
{
printf(errorMessage);
}
void ClearWinSock()
{
#if defined WIN32
WSACleanup();
#endif
}
int main(int argc, char *argv[])
{
int port;
if (argc > 1)
port = atoi(argv[1]);
else
port = PROTOPORT;
if (port < 0) {
printf("Bad port number %s \n", argv[1]);
return 0;
}
#if defined WIN32
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
ErrorHandler("Error at WSAStartup()\n");
return 0;
}
#endif
//creazione della socket
int MySocket;
MySocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (MySocket < 0) {
ErrorHandler("socket creation failed.\n");
ClearWinSock();
return 0;
}
//ASSEGNAZIONE DI UN INDIRIZZO ALLA SOCKET
struct sockaddr_in sad;
memset(&sad, 0, sizeof(sad)); // ensures that extra bytes contain 0
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = inet_addr("127.0.0.1");
sad.sin_port = htons(port); /* converts values between the host and
network byte order. Specifically, htons() converts 16-bit quantities
from host byte order to network byte order. */
if (bind(MySocket, (struct sockaddr*) &sad, sizeof(sad)) < 0) {
ErrorHandler("bind() failed.\n");
closesocket(MySocket);
ClearWinSock();
return 0;
}
// SETTAGGIO DELLA SOCKET ALL'ASCOLTO
if (listen(MySocket, QLEN) < 0) {
ErrorHandler("listen() failed.\n");
closesocket(MySocket);
ClearWinSock();
return 0;
}
// ACCETTARE UNA NUOVA CONNESSIONE
struct sockaddr_in cad; // structure for the client address
int clientSocket; // socket descriptor for the client
int clientLen; // the size of the client address
printf("Waiting for a client to connect...");
while (1) {
clientLen = sizeof(cad); // set the size of the client address
if ((clientSocket = accept(MySocket, (struct sockaddr *)&cad,
&clientLen)) < 0) {
ErrorHandler("accept() failed.\n");
//RICEZIONE DATI TEST
int bytesRcvd;
int totalBytesRcvd = 0;
int Csocket;
Csocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
char buf[BUFFERSIZE]; // buffer for data from the server
printf("Received: "); // Setup to print the echoed string
if ((bytesRcvd = recv(Csocket, buf, BUFFERSIZE - 1, 0)) <= 0) {
ErrorHandler("recv() failed or connection closed prematurely");
closesocket(Csocket);
ClearWinSock();
return 0;
}
totalBytesRcvd += bytesRcvd; // Keep tally of total bytes
buf[bytesRcvd] = '\0'; // Add \0 so printf knows where to stop
printf("%s", buf); // Print the echo buffer
// CHIUSURA DELLA CONNESSIONE
closesocket(MySocket);
ClearWinSock();
return 0;
}
printf("Handling client %s\n", inet_ntoa(cad.sin_addr));
}
}
and client side:
#include "stdafx.h"
#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>
#define BUFFERSIZE 512
#define PROTOPORT 5193
void ErrorHandler(char *errorMessage) {
printf(errorMessage);
}
void ClearWinSock() {
WSACleanup();
}
int main(void) {
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("error at WSASturtup\n");
return 0;
}
// CREAZIONE DELLA SOCKET
int Csocket;
Csocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Csocket < 0) {
ErrorHandler("socket creation failed.\n");
closesocket(Csocket);
ClearWinSock();
return 0;
}
// COSTRUZIONE DELL’INDIRIZZO DEL SERVER
struct sockaddr_in sad;
memset(&sad, 0, sizeof(sad));
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = inet_addr("127.0.0.1"); // IP del server
sad.sin_port = htons(5193); // Server port
// CONNESSIONE AL SERVER
if (connect(Csocket, (struct sockaddr *)&sad, sizeof(sad)) < 0)
{
ErrorHandler("Failed to connect.\n");
closesocket(Csocket);
ClearWinSock();
return 0;
}
char* inputString = "prova"; // Stringa da inviare
int stringLen = strlen(inputString); // Determina la lunghezza
// INVIARE DATI AL SERVER
if (send(Csocket, inputString, stringLen, 0) != stringLen) {
ErrorHandler("send() sent a different number of bytes than expected");
closesocket(Csocket);
ClearWinSock();
return 0;
}
// RICEVERE DATI DAL SERVER
int bytesRcvd;
int totalBytesRcvd = 0;
char buf[BUFFERSIZE]; // buffer for data from the server
printf("Received: "); // Setup to print the echoed string
while (totalBytesRcvd < stringLen) {
if ((bytesRcvd = recv(Csocket, buf, BUFFERSIZE - 1, 0)) <= 0) {
ErrorHandler("recv() failed or connection closed prematurely");
closesocket(Csocket);
ClearWinSock();
return 0;
}
totalBytesRcvd += bytesRcvd; // Keep tally of total bytes
buf[bytesRcvd] = '\0'; // Add \0 so printf knows where to stop
printf("%s", buf); // Print the echo buffer
}
// CHIUSURA DELLA CONNESSIONE
closesocket(Csocket);
ClearWinSock();
printf("\n"); // Print a final linefeed
system("pause");
return(0);
}
I have problems in output the string i've passed from client to server: "prova".
Can someone tell me where is error? The code doesn't give me any error.

You are receiving data only when accept failed:
if ((clientSocket = accept(MySocket, (struct sockaddr *)&cad,
&clientLen)) < 0) {
ErrorHandler("accept() failed.\n");
int bytesRcvd;
int totalBytesRcvd = 0;
...
What you need to do is just add a else case:
if ((clientSocket = accept(MySocket, (struct sockaddr *)&cad,
&clientLen)) < 0) {
ErrorHandler("accept() failed.\n");
} else {
int bytesRcvd;
int totalBytesRcvd = 0;
... // receive code here
// clientSocket is the socket to communicate with client
// call recv on it, not the other socket you created in the loop
}

The accept() call returns 'clientSocket', which you promptly ignore and dream up some new 'Csocket' to receive on.
Don't do that.
if ((bytesRcvd = recv(clientSocket, buf, BUFFERSIZE - 1, 0)) <= 0) {

This is the new Server side:
#include "stdafx.h"
#include <winsock.h>
#include <stdio.h>
#include<stdlib.h>
#define PROTOPORT 5193
#define QLEN 6
#define BUFFERSIZE 512
void ErrorHandler(char *errorMessage)
{
printf(errorMessage);
}
void ClearWinSock()
{
#if defined WIN32
WSACleanup();
#endif
}
int main(int argc, char *argv[])
{
int port;
if (argc > 1)
port = atoi(argv[1]);
else
port = PROTOPORT;
if (port < 0) {
printf("Bad port number %s \n", argv[1]);
return 0;
}
#if defined WIN32
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
ErrorHandler("Error at WSAStartup()\n");
return 0;
}
#endif
//creazione della socket
int MySocket;
MySocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (MySocket < 0) {
ErrorHandler("socket creation failed.\n");
ClearWinSock();
return 0;
}
//ASSEGNAZIONE DI UN INDIRIZZO ALLA SOCKET
struct sockaddr_in sad;
memset(&sad, 0, sizeof(sad)); // ensures that extra bytes contain 0
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = inet_addr("127.0.0.1");
sad.sin_port = htons(port); /* converts values between the host and
network byte order. Specifically, htons() converts 16-bit quantities
from host byte order to network byte order. */
if (bind(MySocket, (struct sockaddr*) &sad, sizeof(sad)) < 0) {
ErrorHandler("bind() failed.\n");
closesocket(MySocket);
ClearWinSock();
return 0;
}
// SETTAGGIO DELLA SOCKET ALL'ASCOLTO
if (listen(MySocket, QLEN) < 0) {
ErrorHandler("listen() failed.\n");
closesocket(MySocket);
ClearWinSock();
return 0;
}
// ACCETTARE UNA NUOVA CONNESSIONE
struct sockaddr_in cad; // structure for the client address
int clientSocket; // socket descriptor for the client
int clientLen; // the size of the client address
printf("Waiting for a client to connect...");
while (1) {
clientLen = sizeof(cad); // set the size of the client address
if ((clientSocket = accept(MySocket, (struct sockaddr *)&cad,
&clientLen)) < 0) {
ErrorHandler("accept() failed.\n");
}else{
//RICEZIONE DATI TEST
int bytesRcvd;
int totalBytesRcvd = 0;
char buf[BUFFERSIZE]; // buffer for data from the server
printf("Received: "); // Setup to print the echoed string
if ((bytesRcvd = recv(clientSocket, buf, BUFFERSIZE - 1, 0)) <= 0) {
ErrorHandler("recv() failed or connection closed prematurely");
closesocket(clientSocket);
ClearWinSock();
return 0;
totalBytesRcvd += bytesRcvd; // Keep tally of total bytes
buf[bytesRcvd] = '\0'; // Add \0 so printf knows where to stop
printf("%s", buf); // Print the echo buffer
} Sleep(10);
// CHIUSURA DELLA CONNESSIONE
closesocket(MySocket);
ClearWinSock();
return 0;
}
printf("Handling client %s\n", inet_ntoa(cad.sin_addr));
system("pause");
}
}

Related

What`s wrong with this socket select code?

#include <stdio.h>
#include <time.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#pragma comment(lib, "WS2_32.lib")
#define IP_ADDRESS "127.0.0.1"
#define PORT 20000
#define BUF_SIZE 64
#undef FD_SETSIZE
#define FD_SETSIZE 10000
void shuffle_buffer(char* buf, size_t size);
SOCKET create_socket();
void send_data(SOCKET sock);
int main()
{
WSADATA ws;
if (WSAStartup(MAKEWORD(2, 2), &ws) != 0)
{
printf("Init Windows Socket Failed::%d\n", GetLastError());
return -1;
}
const int CLIENT_SIZE = 1;
SOCKET socks[CLIENT_SIZE];
struct timeval tv = { 0, 10 };
fd_set fd_read, fd_write;
FD_ZERO(&fd_read);
FD_ZERO(&fd_write);
for (int i = 0; i < CLIENT_SIZE; i++) {
SOCKET sock = create_socket();
socks[i] = sock;
FD_SET(sock, &fd_write);
FD_SET(sock, &fd_read);
}
Sleep(1000);
int number_to_recv = CLIENT_SIZE;
while (number_to_recv > 0) {
int ret = select(CLIENT_SIZE, &fd_read, &fd_write, NULL, &tv);
for (int i = 0; i < CLIENT_SIZE; i++) {
if (FD_ISSET(socks[i], &fd_read)) {
char buf[BUF_SIZE];
int n = recv(socks[i], buf, BUF_SIZE, 0);
buf[n] = 0;
printf("%s\n", buf);
number_to_recv--;
}
if (FD_ISSET(socks[i], &fd_write)) {
send_data(socks[i]);
FD_CLR(socks[i], &fd_write);
//Sleep(1);
}
}
//printf("ret and number : %d, %d\n", ret, number_to_recv);
}
for (int i = 0; i < CLIENT_SIZE; i++) {
closesocket(socks[i]);
}
WSACleanup();
}
SOCKET create_socket()
{
SOCKET cli_sock;
struct sockaddr_in addr;
if ((cli_sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf("Create Socket Failed::%d\n", GetLastError());
return -1;
}
//inet_pton
memset(addr.sin_zero, 0x00, 8);
addr.sin_family = AF_INET;
inet_pton(AF_INET, IP_ADDRESS, (void*)(&addr.sin_addr.s_addr));
addr.sin_port = htons(PORT);
if (connect(cli_sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
{
printf("Connect Error::%d\n", GetLastError());
return -1;
}
return cli_sock;
}
void send_data(SOCKET sock)
{
const int SEND_SIZE = BUF_SIZE / 2;
char buf[SEND_SIZE] = { 0 };
memset(buf, 'a', SEND_SIZE);
shuffle_buffer(buf, SEND_SIZE);
if (send(sock, buf, SEND_SIZE, 0) == SOCKET_ERROR)
{
printf("Send Info Error::%d\n", GetLastError());
}
}
void shuffle_buffer(char* buf, size_t size)
{
for (int i = 0; i < size; i++) {
buf[i] += int(rand() % 26);
}
}
Code above is a socket client using select model run on Win10, the problem is after I send data, but I can not receive data(I am sure that server has sent back data), this code below doesn`t run, so what is the problem? Thanks
The first parameter in select is maxfdp, and I know the difference between Win and Unix, so on Windows, this parameter seems not necessary, and I can write data,
but can not receive it.
if (FD_ISSET(socks[i], &fd_read)) {
char buf[BUF_SIZE];
int n = recv(socks[i], buf, BUF_SIZE, 0);
buf[n] = 0;
printf("%s\n", buf);
number_to_recv--;
}
select removes the sockets from the fd_set if they are not readable/writable. You need to add them back in before the next time you call select.
The reason your code can write data is because sockets start out being writable, so they will still be set in fd_write and your code will write data. They don't start out being readable, if no data has been received yet, so they'll be removed from the fd_read set and then your code stops checking whether they are readable.

how to accept multiple clients with a simple winsock tcp server?

I can't figure out how to accept multiple connections for a simple tcp server using winsock.
I've tried a couple different ways and I can't figure out how to get another connection to work. The first call to accept() seems to be the only one that works. Can someone provide a simple example of how to do this or explain what's going on with listen() and accept() here?
#include <string>
#include <Winsock2.h>
WSADATA WsaData;
unsigned char packet_in[64];
unsigned short port = 29992;
unsigned int max_packet_size = sizeof(packet_in);
sockaddr_in xaddress;
SOCKET sock;
SOCKET sock1 = INVALID_SOCKET;
SOCKET sock2 = INVALID_SOCKET;
int main()
{
int r = WSAStartup( MAKEWORD(2,2), &WsaData );
xaddress.sin_family = AF_INET;
xaddress.sin_port = htons(port);
DWORD nonBlocking = 1;
sockaddr_in from;
int fromLength = sizeof( from );
int count = 0;
sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
r = bind(sock, (const sockaddr*) &xaddress, sizeof(sockaddr_in));
if (r != 0) printf("%d\n", WSAGetLastError());
r = listen(sock, SOMAXCONN);
if (r == SOCKET_ERROR)
printf("%d\n",WSAGetLastError());
ioctlsocket(sock, FIONBIO, &nonBlocking);
while(true)
{
if(count == 0)
{
sock1 = accept(sock, NULL, NULL);
}
else if (count == 1)
{
sock2 = accept(sock, NULL, NULL);
}
if(sock1 != INVALID_SOCKET)
count = 1;
if(sock2 != INVALID_SOCKET)
count = 2;
printf("%i\n",count);
}
return 0;
}
I don't know how to network programming on Windows, but it basically looks like on Linux, so this is small example for Linux.
struct sockaddr_in server_addr
socklen_t len = sizeof(server_addr);
...
while(1)
{
struct sockaddr_in client_addr;
int client_fd;
if((client_fd = accept(server_sock, (struct sockaddr*)& client_addr, &len)) < 0)
{
cerr<<"accept() error"<<endl;
continue;
}
...
}
There is full example written in Polish, but you should understand:
full example (find //server.c)
Main differences between network programming on Windows and Linux are structures and classes, so it should give you some knowledge: Beej's guide to network programming
I think from this simple program, You will get better idea :)
// Multi-Client - Server chat application
#include"header.h"
void isr(int n)
{
printf("Client is Disconnected ..\n");
kill(getpid(),9);
return;
}
main()
{
int sockfd,nsfd,len,pid,size;
char buffer[500],buffer1[500];
struct sockaddr_in server;
///////////////////////////////////////////////////////////////////////
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd==0)
{
printf("Socket file is not created socket is fail...\n");
return;
}
////////////////////////////////////////////////////////////////////////
server.sin_family=AF_INET;
server.sin_port=htons(9898);
len = sizeof(server);
/////////////////////////////////////////////////////////////////////
bind(sockfd,(struct sockaddr*)&server,len);
perror("bind");
/////////////////////////////////////////////////////////////
listen(sockfd,5);
perror("listen");
/////////////////////////////////////////////////////////////////
bzero(buffer,sizeof(buffer));
zero(buffer1,sizeof(buffer1));
//////////////////////////////////////////////////////////////////////
while(1)
{
nsfd=accept(sockfd,(struct sockaddr *)&server,&len);
if(nsfd<0)
{
perror("accept");
return;
}
if(fork()==0)
{
while(1)
{
size=recv(nsfd,buffer,sizeof(buffer),0);
if(size==0)
{
printf("Server is Disconnected...\n");
return;
}
printf("Data:%s\n",buffer);
bzero(buffer,sizeof(buffer));
}
}
else
{
printf("Enter the massage:\n");
signal(17,isr);
while(1)
{
gets(buffer);
send(nsfd,buffer,strlen(buffer)+1,0);
bzero(buffer,sizeof(buffer));
}
}
}
}

Memory leak on socket

I'm writing a tcp proxy and while it seem to work it leaves a memory leak behind. I manipulated the code to forward the incoming packet to itself to create 10000 sockets and close them to see where the leak is. However I can't figure it out. I've used deleaker and it doesn't shows any leak(besides a small one that I don't care.)
But then I untick the two boxes and this comes out.
Any help would be appreciated!
Code:
#include <winsock2.h>
#include <stdio.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <tchar.h>
#include <process.h> /* _beginthread() */
// Need to link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
#define PORT "1234" /* Port to listen on */
#define BUF_SIZE 4096 /* Buffer for transfers */
typedef struct {
char *host;
char *port;
SOCKET sock;
}
HandleStruct;
unsigned int S2C(SOCKET from, SOCKET to)
{
char buf[BUF_SIZE];
unsigned int disconnected = 0;
size_t bytes_read, bytes_written;
bytes_read = recv(from, buf, BUF_SIZE, 0);
if (bytes_read == 0) {
disconnected = 1;
}
else {
bytes_written = send(to, buf, bytes_read, 0);
if (bytes_written == -1) {
disconnected = 1;
}
}
return disconnected;
}
unsigned int C2S(SOCKET from, SOCKET to)
{
char buf[BUF_SIZE];
unsigned int disconnected = 0;
size_t bytes_read, bytes_written;
bytes_read = recv(from, buf, BUF_SIZE, 0);
if (bytes_read == 0) {
disconnected = 1;
}
else {
bytes_written = send(to, buf, bytes_read, 0);
if (bytes_written == -1) {
disconnected = 1;
}
}
return disconnected;
}
void handle(void *param)
{
HandleStruct *args = (HandleStruct*) param;
SOCKET client = args->sock;
const char *host = args->host;
const char *port = args->port;
SOCKET server = -1;
unsigned int disconnected = 0;
fd_set set;
unsigned int max_sock;
struct addrinfo *res = NULL;
struct addrinfo *ptr = NULL;
struct addrinfo hints;
/* Get the address info */
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (getaddrinfo(host, port, &hints, &res) != 0) {
perror("getaddrinfo");
closesocket(client);
return;
}
/* Create the socket */
server = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (server == INVALID_SOCKET) {
perror("socket");
closesocket(client);
return;
}
/* Connect to the host */
if (connect(server, res->ai_addr, res->ai_addrlen) == -1) {
perror("connect");
closesocket(client);
return;
}
if (client > server) {
max_sock = client;
}
else {
max_sock = server;
}
/* Main transfer loop */
while (!disconnected) {
FD_ZERO(&set);
FD_SET(client, &set);
FD_SET(server, &set);
if (select(max_sock + 1, &set, NULL, NULL, NULL) == SOCKET_ERROR) {
perror("select");
break;
}
if (FD_ISSET(client, &set)) {
disconnected = C2S(client, server);
}
if (FD_ISSET(server, &set)) {
disconnected = S2C(server, client);
}
}
closesocket(server);
closesocket(client);
fprintf(stderr, "Sockets Closed: %d/%d", server, client);
_endthread();
return;
}
int _tmain(int argc)
{
WORD wVersion = MAKEWORD(2, 2);
WSADATA wsaData;
int iResult;
SOCKET sock;
struct addrinfo hints, *res;
int reuseaddr = 1; /* True */
/* Initialise Winsock */
if (iResult = (WSAStartup(wVersion, &wsaData)) != 0) {
fprintf(stderr, "WSAStartup failed: %dn", iResult);
return 1;
}
char * host = "127.0.0.1";
char * port = "1234";
/* Get the address info */
ZeroMemory(&hints, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(NULL, PORT, &hints, &res) != 0) {
perror("getaddrinfo");
WSACleanup();
return 1;
}
/* Create the socket */
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock == INVALID_SOCKET) {
perror("socket");
WSACleanup();
return 1;
}
/* Enable the socket to reuse the address */
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseaddr,
sizeof(int)) == SOCKET_ERROR) {
perror("setsockopt");
WSACleanup();
return 1;
}
/* Bind to the address */
if (bind(sock, res->ai_addr, res->ai_addrlen) == SOCKET_ERROR) {
perror("bind");
WSACleanup();
return 1;
}
/* Listen */
if (listen(sock, 6500) == SOCKET_ERROR) {
perror("listen");
WSACleanup();
return 1;
}
freeaddrinfo(res);
int i = 0;
HandleStruct *arg;
arg = (HandleStruct *)malloc(sizeof( HandleStruct));
/* Main loop */
while(1) {
int size = sizeof(struct sockaddr);
struct sockaddr_in their_addr;
SOCKET newsock;
ZeroMemory(&their_addr, sizeof (struct sockaddr));
newsock = accept(sock, (struct sockaddr*)&their_addr, &size);
if (newsock == INVALID_SOCKET) {
perror("acceptn");
}
else {
arg->sock = newsock;
arg->host = host;
arg->port = port;
if (i < 10000) {
_beginthread(handle, 0, (void*) arg);
i++;
}
}
}
closesocket(sock);
WSACleanup();
return 0;
}
I'm not familiar with reading the program in the screenshots you posted; however, you should probably be concerned about this line:
arg = (HandleStruct *)malloc(sizeof( HandleStruct));
Here you are allocating memory for a HandleStruct via malloc() which doesn't appear to be cleaned up anywhere with a subsequent call to free(). You pass arg into handle() but still don't deallocate the memory.
It doesn't appear to be handle()'s responsibility to clean arg up, so you should probably have a call to free() after the while loop, or you could allocate the HandleStruct at the beginning of each loop and deallocate it at the end.
Or you could save yourself the hassle and use std::unique_ptr, and optionally change your threads to std::thread, which self-documents who owns the memory etc:
void handle(std::unique_ptr<HandleStruct> args)
{
// Manipulate args
...
}
int main()
{
std::unique_ptr<HandleStruct> pHandle = std::make_unique<HandleStruct>();
for (;;)
{
...
pHandle->sock = newsock;
pHandle->host = host;
pHandle->port = port;
// Create thread:
std::thread t(&handle, pHandle);
// Wait for thread to finish so pHandle doesn't change while we are using it on another thread
// t.join();
}
}
Every socket uses some memory in the operating system.
Here the description in Linux : accept
ENOBUFS, ENOMEM
Not enough free memory. This often means that the memory
allocation is limited by the socket buffer limits, not by the
system memory.
The OS might not clean them up.
You are also trying to create 10000 threads, these might also take some memory, if the creation doesn't fail long before with errno set to EAGAIN.

Multithreaded winsock server not accepting clients c++

So I have a winsock application in which the computer tries to accept a client, and then starts a new thread with the a pointer to the class object with client info which it copies and then deletes with the delete keyword.
The backbone is copied but the beginning of the OOP-structure is my work and the current implementation seems to be giving me some issues.
I noticed the socket might not copy in the correct format, but have no idea on how to fix this. As the client tries to connect it throws me the error message of that the server refused the connection. Anyway, here is the code of the server.
UPDATE:
It's working.
// main.h
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <process.h>
#include <cstring>
#include <iostream>
#include <stdio.h>
#include <memory>
#pragma comment(lib,"ws2_32.lib" )
class clientData{
private:
SOCKET clientSocket;
std::string name;
public:
clientData(SOCKET &clientSock, const char *tName);
clientData(clientData *cliDat);
~clientData();
inline SOCKET *getClientSocket(){
return &clientSocket;
}
inline std::string *getName(){
return &name;
}
};
And here is the main cpp file
// main.cpp
#include "main.h"
unsigned int __stdcall ServClient(void *data);
int main(int argc, char *argv[])
{
WSADATA wsaData;
int iResult;
sockaddr_in addr;
SOCKET sock, client[10];
addr.sin_family = AF_INET;
addr.sin_port = htons(13337);
addr.sin_addr.S_un.S_addr = INADDR_ANY;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);//2.2
if (iResult)
{
printf("WSA startup failed");
return 0;
}
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
printf("Invalid socket");
return 0;
}
int addrlen = sizeof(sockaddr_in);
iResult = bind(sock, (sockaddr*)&addr, sizeof(sockaddr_in));
if (iResult)
{
printf("bind failed %u", GetLastError());
return 0;
}
iResult = listen(sock, SOMAXCONN);
if (iResult)
{
printf("iResult failed %u", GetLastError());
return 0;
}
int iterationCount = 0;
while ((iterationCount < 10 &&
(client[iterationCount] = accept(sock, (SOCKADDR*)&addr, &addrlen)) != SOCKET_ERROR))
{
if (client[iterationCount] == INVALID_SOCKET){
printf("invalid client socket",GetLastError());
continue;
}
++iterationCount;
char tempName[100] = { '\0' };
sprintf_s(tempName, sizeof(tempName), "Client %u", iterationCount);
clientData *tempCLdata = new clientData(client[iterationCount - 1], tempName);
_beginthreadex(0, 0, ServClient, (void*)tempCLdata, 0, 0);
tempCLdata = nullptr;
}
return 0;
}
unsigned int __stdcall ServClient(void *data)
{
clientData cliDat((clientData*)data);
delete (clientData*)data;
printf("Client connected\n");
int recvLen = 1;
char chunk[1024] = { '\0' };
while ((recvLen = recv(*cliDat.getClientSocket(), chunk, 1024, 0)) > 0){
printf("%.*s", recvLen, chunk);
}
if (recvLen == -1)
perror("Socket recv() problem..\n");
else
printf("End of data on socket, closing..\n");
closesocket(*cliDat.getClientSocket());
return 0;
}
clientData::clientData(SOCKET &clientSock, const char *tName){
clientSocket = clientSock;
name.assign(tName);
}
clientData::clientData(clientData *cliDat){
SOCKET *clientSocketPtr = cliDat->getClientSocket();
clientSocket = *clientSocketPtr;
name.assign(cliDat->getName()->c_str());
}
clientData::~clientData(){
}
Also here is the relevant bit of client code, as requested.
char buffer[1023] = { '\0' };
int heartbeatCount = 0;
while (true)
{
sprintf_s(buffer, sizeof(buffer), "Heartbeat %d", heartbeatCount + 1);
send(sock, buffer, strlen(buffer) + 1, 0);
++heartbeatCount;
Sleep(1000);
}

socket programming( server and client on the same computer) something wrong with connection

I'm new to socket programming and I have this client that tries to connect to a server on the same computer. But the server hangs there after bind or accept—cause bind seems to be right but no output. I know that the server works because another client can connect just fine and the client seems to have done that. What causes the server to not see this incoming connection? I'm at the end of my wits here.
And I haven't been used to programming on Mac, so thank you so much for your patience if I have made some foolish mistakes.
My code is as follows:
server.cpp
using namespace std;
#include<iostream>
#include <netinet/in.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#define PORT 8888
#define BACKLOG 20
//#define DEST_IP "127.0.0.1"
int process_conn_server(int s)
{
ssize_t size =0;
char buffer[1024];
for( ; ; )
{
size = read(s,buffer,1024);
if(size == 0)
{
return 0;
}
}
sprintf(buffer, "%d bytes altogether\n", (int)size);
write(s, buffer,strlen(buffer)+1);
return 0;
}
int main(int argc,char *argv[])
{
//cout<<"?";
int ss, sc, r, err;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int opt=1;
pid_t pid;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORT);
ss = socket(AF_INET, SOCK_STREAM, 0);
if(ss<0)
{
cout<<"[process infro]socket error"<<endl;
return -1;
}
cout<<"[process infro]socket successful"<<endl;
r = setsockopt(ss, SOL_SOCKET,SO_REUSEADDR, (void*)&opt,sizeof(opt));
if (r == -1)
{
perror("setsockopt(listen)");
return 0;
}
cout<<"[process infro]sockopt successful"<<endl;
cout<<"?";
err = bind(ss, (struct sockaddr*) &server_addr, sizeof( server_addr));
cout<<"err";
if(err < 0)
{
cout<<"[process infro]bind error"<<endl;
return -1;
}
cout<<"[process infro]bind successful";
err=listen(ss, BACKLOG);
if(err <0)
{
cout<<"[process infro]listen error"<<endl;
return -1;
}
cout<<"[process infro]lisen successful";
for( ; ; )
{
int addrlen = sizeof(struct sockaddr);
sc = accept(ss, (struct sockaddr*)&client_addr, (socklen_t *)&addrlen);
if(sc < 0)
{
continue;
}
pid = fork();
if (pid == 0)
{
close(ss);
process_conn_server(sc);
}
else
{
close(sc);
}
}
//opt=0;
//setsockopt(ss,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(len));
}
client.cpp
using namespace std;
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <time.h>
#include <arpa/inet.h>
#include <fstream.h>
#define PORT 8888
#define DEST_IP "127.0.0.1"
void process_conn_client(int s)
{
ssize_t size = 0;
char buffer[1024];
//read from the file to be sent
fstream outfile("programm.txt",ios::in|ios::out);
if (outfile.fail())
{
printf("[process infro]cannot open the file to be sent\n");
return ;
}
printf("[process infro]successfully open the file to be sent\n");
while(!outfile.eof())
{
outfile.getline(buffer,1025,'\n');
write(s,buffer,1024);
size = read(s, buffer, 1024);
if(size = 0)
{
return ;
}
//write to the server
write(s,buffer,size);
//get response from the server
size=read(s,buffer,1024);
write(1,buffer,size);
}
outfile.close(); //关闭文件
}
int main(int argc,char *argv[])
{
int s;
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(DEST_IP);
server_addr.sin_port = htons(PORT);
s = socket(AF_INET, SOCK_STREAM, 0);
if(s < 0)
{
cout<<"[process infro]socke error"<<endl;
return -1;
}
cout<<"[process infro] socket built successfully\n";
//inet_pton(AF_INET, argv[1], &server_addr.sin_addr);
connect(s, (struct sockaddr*)&server_addr, sizeof(struct sockaddr));
cout<<"[process infor] connected\n";
process_conn_client(s);
close(s);
return 0;
}
This may be unrelated.... but it won't fit in a comment...
In your server you do this:
int process_conn_server(int s)
{
ssize_t size =0;
char buffer[1024];
for( ; ; )
{
// keep reading until read returns 0
size = read(s,buffer,1024);
if(size == 0)
{
return 0;
}
}
sprintf(buffer, "%d bytes altogether\n", (int)size);
write(s, buffer,strlen(buffer)+1);
return 0;
}
In your client you do this:
void process_conn_client(int s)
{
ssize_t size = 0;
char buffer[1024];
//read from the file to be sent
fstream outfile("programm.txt",ios::in|ios::out);
if (outfile.fail())
{
printf("[process infro]cannot open the file to be sent\n");
return ;
}
printf("[process infro]successfully open the file to be sent\n");
while(!outfile.eof())
{
outfile.getline(buffer,1025,'\n');
// write to server?
write(s,buffer,1024);
// read from server?
size = read(s, buffer, 1024);
if(size = 0)
{
return ;
}
//write to the server
write(s,buffer,size);
//get response from the server
size=read(s,buffer,1024);
write(1,buffer,size);
}
outfile.close();
}
It's a bit hard to follow because of your variable names, but it looks like your client is working under the assumption that your server will send back a response for every chunk of data received, which isn't the case. You server doesn't appear to have changed the accepted socket to non-blocking, so it's going to block on the read call until there is some data to read (it's never going to get 0)...
Are you sure it's failing before this point? Do you have some sample output?
Aso, in your call to accept, you pass addrlen...
int addrlen = sizeof(struct sockaddr);
I think this should be:
int addrlen = sizeof(struct sockaddr_in); /* sizeof(client_addr) */