Send/receive data with python socket

Kolibri picture Kolibri · Feb 23, 2017 · Viewed 31.2k times · Source

I have a vpn (using OpenVPN) with mulitple clients connected to a server (at DigitalOcean). The connection is very good and I am able access every client placed behind their respective firewalls when they are connected to their respective routers through ssh. I want to use python scripts to automatically send files from multiple clients to server and vice versa. Here's the code I am using so far:

Server:

#!/usr/bin/env python

import socket
from threading import Thread
from SocketServer import ThreadingMixIn

class ClientThread(Thread):

    def __init__(self,ip,port):
        Thread.__init__(self)
        self.ip = ip
        self.port = port
        print "[+] New thread started for "+ip+":"+str(port)


    def run(self):
        while True:
            data = conn.recv(2048)
            if not data: break
            print "received data:", data
            conn.send(data)  # echo

TCP_IP = '0.0.0.0'
TCP_PORT = 62
BUFFER_SIZE = 1024  # Normally 1024


tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.bind((TCP_IP, TCP_PORT))
threads = []

while True:
    tcpsock.listen(4)
    print "Waiting for incoming connections..."
    (conn, (ip,port)) = tcpsock.accept()
    newthread = ClientThread(ip,port)
    newthread.start()
    threads.append(newthread)

for t in threads:
    t.join()

Client:

#!/usr/bin/env python

import socket


TCP_IP = '10.8.0.1'
TCP_PORT = 62

BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
s.close()

print "received data:", data

The problem is im not able to get a connection. The server only prints "Waiting for incoming connections..." and the client does not seem to find its way to the server. Is there anyone who can take a look at this and give me some feedback on wath I am doing wrong?

Answer

Nihal Sharma picture Nihal Sharma · Feb 23, 2017

Can you try something like this?

import socket
from threading import Thread


class ClientThread(Thread):

    def __init__(self,ip,port):
    Thread.__init__(self)
    self.ip = ip
    self.port = port
    print "[+] New thread started for "+ip+":"+str(port)


def run(self):
    while True:
        data = conn.recv(2048)
        if not data: break
        print "received data:", data
        conn.send(b"<Server> Got your data. Send some more\n")

TCP_IP = '0.0.0.0'
TCP_PORT = 62
BUFFER_SIZE = 1024  # Normally 1024
threads = []

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(("0.0.0.0", 5000))
server_socket.listen(10)

read_sockets, write_sockets, error_sockets = select.select([server_socket], [], [])

while True:
    print "Waiting for incoming connections..."
    for sock in read_sockets:
        (conn, (ip,port)) = server_socket.accept()
        newthread = ClientThread(ip,port)
        newthread.start()
        threads.append(newthread)

for t in threads:
    t.join()

Now the client will have something like below:

import socket, select, sys

TCP_IP = '0.0.0.0'
TCP_PORT = 62

BUFFER_SIZE = 1024
MESSAGE = "Hello, Server. Are you ready?\n"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, 5000))
s.send(MESSAGE)
socket_list = [sys.stdin, s]

while 1:
    read_sockets, write_sockets, error_sockets = select.select(socket_list, [], [])


    for sock in read_sockets:
        # incoming message from remote server
        if sock == s:
            data = sock.recv(4096)
            if not data:
                print('\nDisconnected from server')
                sys.exit()
            else:
                sys.stdout.write("\n")
                message = data.decode()
                sys.stdout.write(message)
                sys.stdout.write('<Me> ')
                sys.stdout.flush()

        else:
            msg = sys.stdin.readline()
            s.send(bytes(msg))
            sys.stdout.write('<Me> ')
            sys.stdout.flush()

The output is as below:

For server -

Waiting for incoming connections...
[+] New thread started for 127.0.0.1:52661
received data: Hello, World!
Waiting for incoming connections...

received data: Hi!

received data: How are you?

For client -

<Server> Got your data. Send some more
<Me> Hi!
<Me> 
<Server> Got your data. Send some more
<Me> How are you?
<Me> 
<Server> Got your data. Send me more
<Me>

In case you want to have an open connection between the client and server, just keep the client open in an infinite while loop and you can have some message handling at the server end as well. If you need that I can edit the answer accordingly. Hope this helps.