I'm trying to build a client and a server in the same program. For example, user 1 sends a packet of data to user 2, user 2 after receiving the packet sends back a different packet to user 1. The problem is, after running the program neither user receives the packets.

#pragma comment(lib,"ws2_32.lib")
#include <WinSock2.h>
#include <iostream>

static char buffer[8096 + 1];
char a[256] = {};
char MOTD[256];

int main()
{
    //WinSock Startup
    WSAData wsaData;
    WORD DllVersion = MAKEWORD(2, 1);
    if (WSAStartup(DllVersion, &wsaData) != 0) //If WSAStartup returns anything other than 0, then that means an error has occured in the WinSock Startup.
    {
        MessageBoxA(NULL, "WinSock startup failed", "Error", MB_OK | MB_ICONERROR);
        return 0;
    }

    SOCKADDR_IN addr; //Address that we will bind our listening socket to
    int addrlen = sizeof(addr); //length of the address (required for accept call)
    addr.sin_addr.s_addr = inet_addr(INADDR_ANY); //Broadcast locally
    addr.sin_port = htons(1111); //Port
    addr.sin_family = AF_INET; //IPv4 Socket

    SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL); //Create socket to listen for new connections
    bind(sListen, (SOCKADDR*)&addr, sizeof(addr)); //Bind the address to the socket
    listen(sListen, SOMAXCONN); //Places sListen socket in a state in which it is listening for an incoming connection. Note:SOMAXCONN = Socket Oustanding Max Connections

    SOCKET newConnection;
    newConnection = accept(sListen, (SOCKADDR*)&addr, &addrlen);
    if (newConnection == 0){
        std::cout << "Failed to accept the client's connection." << std::endl;
    }else{
        std::cout << "Client Connected!" << std::endl;
    }

    for( int i=0;i< 10;i++ ){
        if (connect(newConnection, (SOCKADDR*)&addr, sizeof(addr)) != 0) //If we are unable to connect...
        {
            MessageBoxA(NULL, "Failed to Connect", "Error", MB_OK | MB_ICONERROR);
             std::cout << WSAGetLastError();

        }else{
            std::cout << 123;
        }
    }

      while (true){

            std::cin >> a;
            send(newConnection, a, sizeof(a), NULL);

            recv(newConnection, MOTD, sizeof(MOTD), NULL);
            std::cout << "MOTD:" << MOTD << std::endl;
    }

    system("pause");
    return 0;
}

Recommended Answers

All 12 Replies

Your topic doesn't seem to match your post content. Also, you didn't ask a question.

For the topic I've yet to see a non-threading solution. That is to do simultaneous work I had to spin up another thread or instance to achieve simultaneous work.

I put the server and client in 2 threads separately, still data is not sent between 2 instances of my program.

#pragma comment(lib,"ws2_32.lib")
#include <WinSock2.h>
#include <iostream>
#include <thread>

static const int num_threads = 2;

static char buffer[8096 + 1];
char a[256] = {};
char MOTD[256];

void call_from_thread(int tid) {
    if( tid == 0 ){
        //WinSock Startup
        WSAData wsaData;
        WORD DllVersion = MAKEWORD(2, 1);
        if (WSAStartup(DllVersion, &wsaData) != 0){MessageBoxA(NULL, "WinSock startup failed", "Error", MB_OK | MB_ICONERROR);}

        SOCKADDR_IN addr;
        int addrlen = sizeof(addr);
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        addr.sin_port = htons(1111);
        addr.sin_family = AF_INET;

        SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL);
        bind(sListen, (SOCKADDR*)&addr, sizeof(addr));
        listen(sListen, SOMAXCONN);

        SOCKET newConnection;
        newConnection = accept(sListen, (SOCKADDR*)&addr, &addrlen);
        if (newConnection == 0){
            std::cout << "Failed to accept the client's connection." << std::endl;
        }else{
            std::cout << "Client Connected!" << std::endl;
        }

        while (true){
            std::cin >> a;
            send(newConnection, a, sizeof(a), NULL);
        }

    }else if( tid == 1 ){
        //Winsock Startup
        WSAData wsaData;
        WORD DllVersion = MAKEWORD(2, 1);
        if (WSAStartup(DllVersion, &wsaData) != 0){MessageBoxA(NULL, "Winsock startup failed", "Error", MB_OK | MB_ICONERROR);}

        SOCKADDR_IN addr;
        int sizeofaddr = sizeof(addr);
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        addr.sin_port = htons(1111);
        addr.sin_family = AF_INET;

        SOCKET Connection = socket(AF_INET, SOCK_STREAM, NULL); //Set Connection socket
        if (connect(Connection, (SOCKADDR*)&addr, sizeofaddr) != 0) //If we are unable to connect...
        {
            MessageBoxA(NULL, "Failed to Connect", "Error", MB_OK | MB_ICONERROR);
            //return 0; //Failed to Connect
        }

        std::cout << "Connected!" << std::endl;

        char MOTD[256];
        while (true){
            recv(Connection, MOTD, sizeof(MOTD), NULL); //Receive Message of the Day buffer into MOTD array
            std::cout << "MOTD:" << MOTD << std::endl;
        }
    }
}
int main() {
         std::thread t[num_threads];

         for (int i = 0; i < num_threads; ++i) {
             t[i] = std::thread(call_from_thread, i);
         }

         for (int i = 0; i < num_threads; ++i) {
             t[i].join();
         }

    return 0;
}

Where do you think the issue is? That is, why not add debug statements to see what is happening?

Also, there are many systems where firewalls eat or block such work.

My code works if I build a server app and a client app separately. I put the code in 2 thread because I want it to work in the same app. The user on stackoverflow had the problem when building a server and client separately

Same app, OK, but I see no reason for this to work in some simultaneous (your title) action given the first post.

You need to debug your code. Add prints, etc. Also watch out for what ports you use since you can't use the same port for more than one connection. That's something basic I see new programmers run into a lot.

This is what I came up to:

#pragma comment(lib,"ws2_32.lib")
#include <WinSock2.h>
#include <iostream>
#include <thread>

static const int num_threads = 2;

static char buffer[8096 + 1];
char a[256] = {};
char MOTD[256];

void call_from_thread(int tid) {
    if( tid == 0 ){
        //WinSock Startup
        WSAData wsaData;
        WORD DllVersion = MAKEWORD(2, 1);
        if (WSAStartup(DllVersion, &wsaData) != 0){MessageBoxA(NULL, "WinSock startup failed", "Error", MB_OK | MB_ICONERROR);}

        SOCKADDR_IN addr;
        int addrlen = sizeof(addr);
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        addr.sin_port = htons(1111);
        addr.sin_family = AF_INET;

        SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL);
        bind(sListen, (SOCKADDR*)&addr, sizeof(addr));
        listen(sListen, SOMAXCONN);

        SOCKET newConnection;
        newConnection = accept(sListen, (SOCKADDR*)&addr, &addrlen);
        if (newConnection == 0){
            std::cout << "Failed to accept the client's connection." << std::endl;
        }else{
            std::cout << "Client Connected!" << std::endl;
        }

        while (true){
            std::cin >> a;
            send(newConnection, a, sizeof(a), NULL);
        }

    }else if( tid == 1 ){
        //Winsock Startup
        WSAData wsaData;
        WORD DllVersion = MAKEWORD(2, 1);
        if (WSAStartup(DllVersion, &wsaData) != 0){MessageBoxA(NULL, "Winsock startup failed", "Error", MB_OK | MB_ICONERROR);}

        SOCKADDR_IN addr;
        int sizeofaddr = sizeof(addr);
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        addr.sin_port = htons(1111);
        addr.sin_family = AF_INET;

        SOCKET Connection = socket(AF_INET, SOCK_STREAM, NULL); //Set Connection socket
        if (connect(Connection, (SOCKADDR*)&addr, sizeofaddr) != 0) //If we are unable to connect...
        {
            MessageBoxA(NULL, "Failed to Connect", "Error", MB_OK | MB_ICONERROR);
            //return 0; //Failed to Connect
        }else{
             std::cout << "Connected Client!" << std::endl;
        }

        char MOTD[256];
        while (true){
            recv(Connection, MOTD, sizeof(MOTD), NULL); //Receive Message of the Day buffer into MOTD array
            std::cout << "MOTD:" << MOTD << std::endl;
        }
    }
}
int main() {
         std::thread t[num_threads];

         for (int i = 0; i < num_threads; ++i) {
             t[i] = std::thread(call_from_thread, i);
         }

         for (int i = 0; i < num_threads; ++i) {
             t[i].join();
         }

    return 0;
}

Still, it doesn't work, no data is sent between apps. Can you point me in the right direction

Remember I asked you to think about the port numbers? I only see 1111 in all the code so if this is on the same PC, same app but two instances, why would that work?

Is there a way to make it work both on the same pc, same app and to work on diffrent PCs? I changed the port to 1112 for the client part and 1111 for server part but it doesn't work

It's your design. That is, you get to work out what ports to use and to connect to for your apps.

For your server, it would listen on some port, the client would connect to that port and the server would respond to the client requests. The client (a nice one) would disconnect when done.

For 2 apps with some client+server in each, that would be 2 server ports. Right? And how would your app know if it was first or second? (neat problem to solve in itself!)

PS. I was unclear. Let's keep it short. You can't have two servers listening on the same port. Which will answer? Think about it.
Same for a client. It can't share it's port either. Who gets the answer?

Member Avatar for kevenm

I'm not as quick a Windows programmer,
but thought I'd give this code a try.
So slight conversion of socket stuff to compile on Linux.
(not as quick with threads either, so used fork to create
child processes)

I added error code to each of the socket calls
socket, bind, listen, accept, connect, send, recv.
(basically output that I had an error, and errno)

I got error 111 "Connection refused".

What I saw was a timing issue.
The "client" trying to connect, was quicker than
the "server" trying to listen.
Therefore there was no server to connect to.

I added a "sleep (2)", basically a pause in the client
to allow the server to get started.

And it connected !!

On server side, I also added some "ending" code so
I could shutdown via client, instead of killing the whole thing.

while (true){
  if (!fgets (a, sizeof(a), stdin)) //KDM
    break;
  int len = send(newConnection, a, sizeof(a), 0);
  if (len < 0) {
    fprintf (stderr, "send err %d %s\n", errno, strerror (errno));
    break;
  }
  if (strncmp (a, "STOP", 4) == 0 ) //KDM
    break;
}
close (newConnection);
fprintf (stderr, "server done\n"); //KDM

Dang, now you'll see I'm not much a C++ programmer either.

But this tells me your code is good.
I suspect just a timing issue.
Those error checks are important!!

int Connection = socket(AF_INET, SOCK_STREAM, 0);
if (connect(Connection, (struct sockaddr*)&addr, sizeofaddr) != 0) {
  fprintf (stderr, "Failed to Connect %d %s\n", errno, strerror(errno));
  exit (6);
}else{
  fprintf (stderr, "Connected Client!\n");
}

Run Example:
$ code
thread 0
thread 1
Client Connected!
Connected Client!
Happy Day
Happy Day

STOP
server done
STOP

client done
thread 0 stat 0
thread 1 stat 0
$

commented: "Hello?", the other person has their earbuds in! +15
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.