How to make multithread socket on different vms - python

I want to implement multithreaded-server receives connection from multiple clients on different VMs. 3 VMs are in the same subnet. I would ask how to make it can connect to each other by configuring the network on vms and how to change ip and port in code. Here is the code on server:
import socket
from threading import Thread
from SocketServer import ThreadingMixIn
TCP_IP = 'localhost'
TCP_PORT = 12345
BUFFER_SIZE = 1024
class ClientThread(Thread):
def __init__(self,ip,port,sock):
Thread.__init__(self)
self.ip = ip
self.port = port
self.sock = sock
print " New thread started for "+ip+":"+str(port)
def run(self):
filename='mytext.txt'
f = open(filename,'rb')
while True:
l = f.read(BUFFER_SIZE)
while (l):
self.sock.send(l)
l = f.read(BUFFER_SIZE)
if not l:
f.close()
self.sock.close()
break
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(5)
print "Waiting for incoming connections..."
(conn, (ip,port)) = tcpsock.accept()
print 'Got connection from ', (ip,port)
newthread = ClientThread(ip,port,conn)
newthread.start()
threads.append(newthread)
for t in threads:
t.join()
Client1:
import socket
TCP_IP = 'localhost'
TCP_PORT = 12345
BUFFER_SIZE = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
with open('received_file', 'wb') as f:
print 'file opened'
while True:
data = s.recv(BUFFER_SIZE)
print('data=%s', (data))
if not data:
f.close()
print 'file close()'
break
f.write(data)
s.close()
print('connection closed')
Client2:
import socket
TCP_IP = 'localhost'
TCP_PORT = 12345
BUFFER_SIZE = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
with open('received_file', 'wb') as f:
print 'file opened'
while True:
data = s.recv(BUFFER_SIZE)
print('data=%s', (data))
if not data:
f.close()
print 'file close()'
break
f.write(data)
s.close()
print('connection closed')

When you are binding to "localhost" IP address it means that your server starts listening on "loopback" internal virtual networking interface with address 127.0.0.1 which can be accessed from local machine but not from outside.
Your server does not listen on any physical interfaces which look into world so even properly configured clients would not be able to connect to your server from remote nodes.
You can replace "localhost" with "0.0.0.0" - which means "bind to all available interfaces".
This means that you can start your server without knowledge of IP address(es) of your own server.
It will be waiting incoming connections on all physical and virtual interfaces which are configured in your VM.
TCP_IP = '0.0.0.0'
tcpsock.bind((TCP_IP, TCP_PORT))
But clients need to know IP address of your server to be able to connect to it.
Right now your clients try to connect to theirs own VM by using IP address 127.0.0.1
You need to provide clients with real IP address of your server for them to connect to it.
Lets assume that your server has address 192.168.4.4
Then your client code should look this way:
TCP_IP = '192.168.4.4'
s.connect((TCP_IP, TCP_PORT))

Related

Can't get client to connect to server

I'm just very confused still about the basic socket process. Tried multiple ways to try and get the socket to connect but it keeps refusing.
client code- socket_client.py
import socket
host = socket.gethostname()
port = 8080
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((host,port))
res = client.send (b' testing data send...')
client.close()
server code- server_client.py
import socket
host = socket.gethostname()
port = 8080
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen(10)
x=0
server_data = []
while True:
conn, addr = server.accept()
data = conn.recv(4096).decode()
x += 1
print ('Servicing client at %s'%addr[0])
server_data = client.recv(4096)
client_close()
server.close()
You have some problems in your server. You read from the connection but never use it, and you do client.recv when there is no variable client. This works:
import socket
host = socket.gethostname()
port = 8080
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen(10)
x=0
server_data = []
while True:
conn, addr = server.accept()
x += 1
print ('Servicing client at %s'%addr[0])
data = conn.recv(4096).decode()
print( "Received", data )
conn.close()
server.close()
Do remember that Python has a SocketServer module that can make some of this easier. If you need to get fancier, there are few modules better than Twisted at this kind of thing.
ALSO remember that the server must be running before you start the client. Someone has to be listening, otherwise the connection is rejected.

Python: simple client server the listening for connections close after first connection close

So i want to build simple Server-Client.
This server gets connections from clients (simple string), do my stuff, return answer, close the client connection and wait for another connections.
Client
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip = '127.0.0.1'
port = 4500
address = (ip, port)
message = 'mymessage'
client = socket.socket()
client.connect(address)
client.sendall(message.encode('utf-8'))
Server
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
name = socket.gethostname()
ip = '127.0.0.1'
port = 4500
address = (ip, port)
server.bind(address)
server.listen(1)
print('Start listening on', ip, ':', port)
client, addr = server.accept()
print('Received connection from', addr[0], ':', addr[1])
while True:
data = client.recv(1024).decode('utf-8')
print('Received', data, 'from the client')
# DO something.....
client.send('Goodbye'.encode('utf-8'))
client.close()
break
So currently after the client get back the response from the server the server is close and i want my server to continue listening for another connections.
Simple, you need to add another loop, so that the server can always listen:
Server
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
name = socket.gethostname()
ip = '127.0.0.1'
port = 4500
address = (ip, port)
server.bind(address)
server.listen(1)
while True:
client, addr = server.accept()
print('Start listening on', ip, ':', port)
print('Received connection from', addr[0], ':', addr[1])
while True:
data = client.recv(1024).decode('utf-8')
print('Received', data, 'from the client')
# DO something.....
client.send('Goodbye'.encode('utf-8'))
client.close()
break

Python Socket connect two devices on same network

I am attempting to connect a simple server and client from two computers on the same network. Both the client and server cannot 'find' each other, as they do not move past .connect() and .accept() respectively. What am I doing wrong?
(Windows 10)
Server:
import socket
HOST = socket.gethostname() #Returns: "WASS104983"
#I have also tried socket.gethostbyname(socket.gethostname)), returning: "25.38.252.147"
PORT = 50007
sock = socket.socket()
sock.bind((HOST, PORT))
sock.listen(5)
print("Awaiting connection... ")
(clnt, addr) = sock.accept()
print("Client connected")
…
and Client:
import socket
HOST = "WASS104983" #Or "25.38.252.147", depending on the servers setup
PORT = 50007
sock = socket.socket()
print("Attempting connection... ")
sock.connect((HOST, PORT))
print("Connected")
…
I have gotten this to work before so I am not sure why it's not now.
I know there are a few questions of this calibre, but none seem to cover my problem.
Also, a wifi extender should not interfere with local transmissions should it?
I have always seen servers setup as such:
import socket
import threading
bind_ip = '0.0.0.0'
bind_port = 9999
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_ip, bind_port))
server.listen(5)
print("[*] Listening on {}:{}".format(bind_ip, bind_port))
def handle_client(client_socket):
request = client_socket.recv(1024)
print('received: {}'.format(request))
client_socket.send(b'ACK!')
client_socket.close()
while True:
client, addr = server.accept()
print("[*] Accepted connection from: {}:{}".format(addr[0], addr[1]))
client_handler = threading.Thread(target=handle_client, args=(client,))
client_handler.start()*
Where I think an important distinction from your post may be that the server accepting connections is within an infinite loop. Have you tried this?

how to refuse socket connection for a Specific IP in Python?

listenr code :
import socket
host = socket.gethostbyname(socket.gethostname())
port = int(raw_input("PORT > "))
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen(5)
while True:
c, addr = server.accept()
buff = 2048
print addr[0]+" connected."
c.send("Connection Established")
data = c.recv(buff)
if data:
print data
client code:
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostbyname(socket.gethostname())
port = int(raw_input("PORT > "))
server.connect((host, port))
buff = 2048
data = server.recv(buff)
if data:
print data
and is it possible to receive data from client and listen on port at the same time ? how?
After accept() use thread to send/receive data to/from client and at the same time main thread can wait for next client running accept() again. It is standard method .

Send/receive data with python socket

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?
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.

Categories