I have some code that acts as a socket server:
import threading
import socketserver
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
ip, port = self.client_address
print("{}:{} connected.".format(ip, port))
try:
while True:
data = str(self.request.recv(1024), 'ascii')
print("{}:{} - {}".format(ip, port, data))
cur_thread = threading.current_thread()
response = bytes("{}: {}".format(cur_thread.name, data), 'ascii')
self.request.sendall(response)
except ConnectionError:
print("{}:{} lost connection.".format(ip, port))
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
def make_server() -> ThreadedTCPServer:
host, port = "127.0.0.1", 9191
server = ThreadedTCPServer((host, port), ThreadedTCPRequestHandler, False)
server.allow_reuse_address = True
server.server_bind()
# Start a thread with the server -- that thread will then start one
# more thread for each request
server_thread = threading.Thread(target=server.serve_forever)
# Exit the server thread when the main thread terminates
server_thread.daemon = True
server_thread.start()
print("Server started.")
return server
And I have tried to connect to the server in my terminal:
>>> from socket import socket
>>> s = socket()
>>> s.connect("127.0.0.1", 9191)
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
What is the cause of this?
Note: this code is imported and ran from another python file - "Server started." is printed when I run the code.
Related
I am currently developping a chat program, and I have a problem.
The server can only receive one information from the client and then stop receiving information.
here's my code :
Server.py
import socket
import threading
# Some base important value
ip = '0.0.0.0'
port = 25565
encoding = 'utf-8'
# Some runtime value
clientList = []
is_server_running = True
# a class representing a client
class ClientThread(threading.Thread):
conn = None
addr = None
# Use to init the thread and the main client value
def __init__(self, conn, addr):
threading.Thread.__init__(self)
self.conn = conn
self.addr = addr
print(f"Successfully created client thread for client {self.addr[0]}:{self.addr[1]}")
# Use to receive and send data
def run(self):
while True:
try:
data = self.conn.recv(1024).decode(encoding)
print(f"Got message from client ({self.addr[0]}:{self.addr[1]}) : \"{data}\"")
except Exception as e:
print(f"Got exception in client {self.addr[0]}:{self.addr[1]} : {str(e)}")
break
clientList.remove(self)
# Create a socket and bind the correct port and ip
print("Creating Server...")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((ip, port))
s.listen(5)
print(f"Server created and launched on port {port}.")
while is_server_running:
try:
# Accept the connection and create a new client thread
conn, adrr = s.accept()
print(f"Got new connection from adress {adrr[0]}:{adrr[1]}. Creating Thread for client")
client_thread = ClientThread(conn, adrr)
client_thread.start()
clientList.append(client_thread)
except Exception as e:
print(f"Got Exception in server listening runtime : {str(e)}. Server Stopped")
is_server_running = False
break
for client in clientList:
client.conn.close()
s.close()
Client.py
import socket
# base important variables
encoding = 'utf-8'
adress = 'here is the server ip'
port = 25565
# runtime variables
is_client_running = True
# Create a socket and connects to the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((adress, port))
message = "Hello !".encode(encoding)
s.sendall(message)
while is_client_running:
message = input(">>> ")
s.sendall(message.encode(encoding))
Output :
Creating Server...
Server created and launched on port 25565.
Got new connection from adress -----------:----. Creating Thread for client
Successfully created client thread for client -----------:----
Got message from client (-----------:----) : "Hello !"
And then when I input something in the client console (like : Goodbye), the server receive nothing.
Thank you for your help !
I'm currently experimenting with sockets in python. I tried the following 3 variants (skip over the code to read the question first):
class Server(threading.Thread):
def __init__(self):
super(Server, self).__init__()
self.ip = "localhost"
self.port = 23071
self.connectionNumber = 0
def run(self):
self.server= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.ip, self.port))
self.server.listen(self.connectionNumber)
print("SERVER: Server is running")
print("SERVER: Waiting for connection")
client, addr = self.server.accept()
print("SERVER: Something connected at {}".format(addr))
time.sleep(10) # Simulating doing something
client.close()
self.server.close()
print("Server is closed")
class Client(threading.Thread):
def __init__(self):
super(Client, self).__init__()
self.ip = "localhost"
self.port = 23071
def run(self):
time.sleep(3) #Ensure the client socket is created after the server socket
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
print("CLIENT. Trying to connect")
self.server.connect((self.ip, self.port))
print("CLIENT. Connection sucessful")
time.sleep(2) # SImulating doing something
except Exception as e:
print("CLIENT: Exception \"{}\" happend".format(e))
finally:
self.server.close()
print("CLIENT: Socket closed")
if __name__ == "__main__":
server = Server()
client = Client()
server.start()
client.start()
server.join()
client.join()
class Server(threading.Thread):
def __init__(self):
super(Server, self).__init__()
self.ip = "localhost"
self.port = 23071
self.connectionNumber = 0
def run(self):
time.sleep(3) #Ensure server socket is created after client socket
self.server= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.ip, self.port))
self.server.listen(self.connectionNumber)
print("SERVER: Server is running")
print("SERVER: Waiting for connection")
client, addr = self.server.accept()
print("SERVER: Something connected at {}".format(addr))
time.sleep(10) # Simulating doing something
client.close()
self.server.close()
print("Server is closed")
class Client(threading.Thread):
def __init__(self):
super(Client, self).__init__()
self.ip = "localhost"
self.port = 23071
def run(self):
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
print("CLIENT. Trying to connect")
self.server.connect((self.ip, self.port))
print("CLIENT. Connection sucessful")
time.sleep(2) # SImulating doing something
except Exception as e:
print("CLIENT: Exception \"{}\" happend".format(e))
finally:
self.server.close()
print("CLIENT: Socket closed")
class Server(threading.Thread):
def __init__(self):
super(Server, self).__init__()
self.ip = "localhost"
self.port = 23071
self.connectionNumber = 0
def run(self):
self.server= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.ip, self.port))
self.server.listen(self.connectionNumber)
print("SERVER: Server is running")
#Ensure the server socket is created when the client wants to make a connection
#but the server isn't waiting for new connections when the client establishes a connection
#(.accept() call delayed)
time.sleep(3)
print("SERVER: Waiting for connection")
client, addr = self.server.accept()
print("SERVER: Something connected at {}".format(addr))
time.sleep(10) # Simulating doing something
client.close()
self.server.close()
print("Server is closed")
class Client(threading.Thread):
def __init__(self):
super(Client, self).__init__()
self.ip = "localhost"
self.port = 23071
def run(self):
time.sleep(1) #Ensure client socket is created after server socket
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
print("CLIENT. Trying to connect")
self.server.connect((self.ip, self.port))
print("CLIENT. Connection sucessful")
time.sleep(2) # SImulating doing something
except Exception as e:
print("CLIENT: Exception \"{}\" happend".format(e))
finally:
self.server.close()
print("CLIENT: Socket closed")
if __name__ == "__main__":
server = Server()
client = Client()
server.start()
client.start()
server.join()
client.join()
In the first variant, a connection can be established without problems. I expected it to be this way, because the server is waiting for new connections with .accept(). In second variant a connection can not be establish, due to the fact, that there is no server socket yet. The connection cannot reach a target (Exception happens. WinError 1106..something). Also expected. But the third one confuses me. I expected that a connection cannot be established, due to the fact that a server socket exists, but the server is not accepting new connections yet (with .accept() not called) and the max. number of connections in the backlog is 0 (.listen(0)). Still the .connect() call of the client is not blocking nor throwing an exception. It states: "CLIENT: Connection sucessful". What happend? I expected the call to block, because I never specified a timeout and the connection will never be accepted.
I hope someone of you can explain it to me what has happend in detail. I found similiar topics here on Stackoverflow and on other sides, but I've not found an answer that got rid of my confusion.
Greetings,
Tmirror
EDIT:
After further investigations with wireshark I found out the following:
server.listen(x) "fires up" the socket. From this point on, the server socket can perform the three way handshake through responding to the client initiating the three way handshake.
server.listen(x) allows up to x elements in the backlog. This means up to x elements can perform the three way handshake. After performing it or during it, they are queued in the backlog. They are taken out of the backlog if the server socket calls .accept(). So the backlog queue always contains client connection which have already performed a 3-way handshake or are doing it currently. x determines the size of this backlog queue.
It seems server.listen(0) has the same effect as server.listen(1). Only one connection will be able to perform the 3-way handshake and be contained in the backlog queue. Therefor my guess is, that the python socket implementation is, that .listen(...) must have an argument value of at least 1. I guess it is adjusted to 1 if it is lower.
Therefor I'd like to change my question a little bit. It is quiet obvious now why socket.connect() doesn't throw an exception or is blocking. It can sucessfully perform the 3-way handshake and the connection is open. But what does socket.accept() do then? It obviously takes one element out of the backlog queue, but what does it mean in terms of communication between server and client and in terms of the tcp protocol?
But what does socket.accept() do then? It obviously takes one element out of the backlog queue, but what does it mean in terms of communication between server and client and in terms of the tcp protocol?
It does nothing in terms of communication between server and client and in terms of the tcp protocol. It just associates a file descriptor of a process with the connection, i. e. it sets up operating system data structure. We can see the effect with netstat, e. g. on Windows with the -b or -o option.
Okay, so I createda socket server in python and I want when someone connects to it to run an application on the sever but which is user controlled. I'll try to explain better with the code.
#!/usr/bin/python
import socket
import select
import os
from time import sleep
class SocketServer:
""" Simple socket server that listens to one single client. """
def __init__(self, host = '0.0.0.0', port = 2010):
""" Initialize the server with a host and port to listen to. """
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.host = host
self.port = port
self.sock.bind((host, port))
self.sock.listen(1)
def close(self):
""" Close the server socket. """
print('Closing server socket (host {}, port {})'.format(self.host, self.port))
if self.sock:
self.sock.close()
self.sock = None
def run_server(self):
""" Accept and handle an incoming connection. """
print('Starting socket server (host {}, port {})'.format(self.host, self.port))
client_sock, client_addr = self.sock.accept()
print('Client {} connected'.format(client_addr))
stop = False
while not stop:
if client_sock:
# Check if the client is still connected and if data is available:
os.system("python vuln.py")
# try:
# rdy_read, rdy_write, sock_err = select.select([client_sock,], [], [])
# except select.error:
# print('Select() failed on socket with {}'.format(client_addr))
# return 1
if len(rdy_read) > 0:
read_data = client_sock.recv(255)
if len(read_data) == 0:
print('{} closed the socket.'.format(client_addr))
stop = True
else:
print('>>> Received: {}'.format(read_data.rstrip()))
if read_data.rstrip() == 'quit':
stop = True
else:
client_sock.send(read_data)
else:
print("No client is connected, SocketServer can't receive data")
stop = True
# Close socket
print('Closing connection with {}'.format(client_addr))
client_sock.close()
return 0
def main():
server = SocketServer()
while (True):
server.run_server()
print 'Exiting'
if __name__ == "__main__":
main()
This is my socket server, which always runs and cand establish multiple connections.
print("Please tell me what's your age")
age = input('> ')
sleep(1)
print("Damn man, sometimes I wish I was %s" % age)
sleep(1)
and this is the app which I want to run on the server and let the user who connects with netcat for example see the same prompt and have the same functionality but on the server.
I'm trying to create a persistent socket connection between a Lua client and Python server. Effectively a script that'll constantly ping the server with keepalive messages
My current issue is that the socket closes after each connection without a means to reopen it for transmission.
Lua Client:
local HOST, PORT = "localhost", 9999
local socket = require('socket')
-- Create the client and initial connection
client, err = socket.connect(HOST, PORT)
client:setoption('keepalive', true)
-- Attempt to ping the server once a second
start = os.time()
while true do
now = os.time()
if os.difftime(now, start) >= 1 then
data = client:send("Hello World")
-- Receive data from the server and print out everything
s, status, partial = client:receive()
print(data, s, status, partial)
start = now
end
end
Python Server:
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
self.data = self.request.recv(1024).strip()
print("{} wrote".format(self.client_address[0]))
print(self.data)
print(self.client_address)
# Send back some arbitrary data
self.request.sendall(b'1')
if __name__ == '__main__':
HOST, PORT = "localhost", 9999
# Create a socketserver and serve is forever
with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
server.serve_forever()
The expected result is a keepalive ping every second to ensure the client is still connected to the server.
I ended up finding a solution.
The problem seems to have been with the socketserver library in Python. I switched it to raw sockets and things began working how I wanted them to. From there I created threads to handle the back and forth in the background
Python Server:
import socket, threading
HOST, PORT = "localhost", 9999
# Ensures the connection is still active
def keepalive(conn, addr):
print("Client connected")
with conn:
conn.settimeout(3)
while True:
try:
data = conn.recv(1024)
if not data: break
message = data.split(b',')
if message[0] == b'ping':
conn.sendall(b'pong' + b'\n')
except Exception as e:
break
print("Client disconnected")
# Listens for connections to the server and starts a new keepalive thread
def listenForConnections():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.bind((HOST, PORT))
while True:
sock.listen()
conn, addr = sock.accept()
t = threading.Thread(target=keepalive, args=(conn, addr))
t.start()
if __name__ == '__main__':
# Starts up the socket server
SERVER = threading.Thread(target=listenForConnections)
SERVER.start()
# Run whatever code after this
The Lua client didn't change in this scenario
the code of socket-server and the code of socket-client can run perfectly on my localhost, but when I run the code of socket-server on Ubuntu server, the code of socket-client on my localhost can't connect to Ubuntu server.And the code of socket-client on Ubuntu Server can't connect to my localhost Server.
socket-server.py
import socket
import threading
def bbs(conn):
user_list.append(conn)
try:
while 1:
msg = conn.recv(1024)
if msg:
for user in user_list:
user.send(msg)
except ConnectionResetError:
user_list.remove(conn)
conn.close()
user_list = []
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('0.0.0.0', 18000))
server.listen()
while 1:
conn, addr = server.accept()
t = threading.Thread(target=bbs, args=(conn,))
t.start()
socket-client.py
import socket
import threading
import time
def send_msg():
while 1:
msg = input()
client.send((name + ':' + msg).encode('utf-8'))
def recv_msg():
while 1:
msg = client.recv(1024)
if msg:
try:
print(msg.decode('utf-8'))
time.sleep(1)
except UnicodeDecodeError:
pass
name = input('请输入你的昵称:')
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('10.26.8.132', 18000))
sendmsg_thread = threading.Thread(target=send_msg)
recvmsg_thread = threading.Thread(target=recv_msg)
sendmsg_thread.start()
recvmsg_thread.start()
Server is always wait for connection, Client report an error:
TimeoutError: [WinError 10060] The connection attempt failed because the connecting party did not respond correctly after a period of time or because the connecting host did not respond.
Wang if this works without issue on your localhost, but not over a network connection, it might be a firewall issue on both client & server. You can use 'nc' (netcat) for testing the connection from client to the server.