Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use socket with a Python client and a C++ server

I have a simple client/server program.

The client is written in python as this :

import socket
import sys

HOST, PORT = "localhost", 50007

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect((HOST, PORT))
for x in range(0, 10000):
    print("Step 1")
    s.send(b'Hello')
    print("Step 2")
    print(str(s.recv(1000)))
    print(x)

And I wrote a server in python like this :

import socket

HOST = ''
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()

while True:
    data = conn.recv(1024)
    conn.sendall(data)

I want to create a C++ version of the server. I did this :

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <string>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>

using namespace std;

#define SERVER_PORT htons(50007)

int main() {

        char buffer[1000];
        int n;

        int serverSock=socket(AF_INET, SOCK_STREAM, 0);

        sockaddr_in serverAddr;
        serverAddr.sin_family = AF_INET;
        serverAddr.sin_port = SERVER_PORT;
        serverAddr.sin_addr.s_addr = INADDR_ANY;

        /* bind (this socket, local address, address length)
           bind server socket (serverSock) to server address (serverAddr).  
           Necessary so that server can use a specific port */ 
        bind(serverSock, (struct sockaddr*)&serverAddr, sizeof(struct sockaddr));

        // wait for a client
        /* listen (this socket, request queue length) */
        listen(serverSock,1);

        while (1 == 1) {
                bzero(buffer, 1000);

                sockaddr_in clientAddr;
                socklen_t sin_size=sizeof(struct sockaddr_in);
                int clientSock=accept(serverSock,(struct sockaddr*)&clientAddr, &sin_size);

                //receive a message from a client
                n = read(clientSock, buffer, 500);
                cout << "Confirmation code  " << n << endl;
                cout << "Server received:  " << buffer << endl;

                strcpy(buffer, "test");
                n = write(clientSock, buffer, strlen(buffer));
                cout << "Confirmation code  " << n << endl;
        }
        return 0;
}

It works one time but it block at the line str(s.recv(1000)) of the client.

This is the output from the client :

Step 1
Step 2
b'test'
0
Step 1
Step 2

And this is the output from the server :

code  5
Server received:  Hello
code  4
code  5
Server received:  Hello
code  4

As you can see, the communication is like this :

  1. The client send a message
  2. The server receive the message
  3. The server send a message
  4. The client send another message
  5. The server receive a message and seems to send another message but the client did not receive it.

What is my error?

like image 620
Dougui Avatar asked Dec 22 '13 19:12

Dougui


People also ask

Can a socket be both server and client?

For a server, you usually create a socket, then bind it to a specific port, and accept connections. For the client, you create a socket, and connect to a specified address (an IP address and port pair for a TCP/IP connection). The same device can run a TCP server and client at the same time.

How do I run a client and server on the same machine python?

If you want to get your HOST IP address of your computer, you can use host = socket. gethostbyname(socket. gethostname()) . Keep port number same on both server and client.

How does python connect to server and client?

To use python socket connection, we need to import socket module. Then, sequentially we need to perform some task to establish connection between server and client. We can obtain host address by using socket. gethostname() function.


2 Answers

In C++ server, you accept connection, read, write, then leak the open socket and go to wait for next client to connect.

Move your accept out of the loop, or add inner loop after accept.

And close the socket when you're done with it, before the variable with socket number goes out of scope.

like image 52
hyde Avatar answered Sep 17 '22 17:09

hyde


One thing that seems strange is that in the C version you have the accept inside the loop.

I think this means that on each iteration it will attempt to make a new socket connection to a new client.

like image 41
Peter de Rivaz Avatar answered Sep 17 '22 17:09

Peter de Rivaz