I have written a telnet server and client, but I don't receive a response from the server and I don't know where the problem is.
SERVER
import socket
import subprocess
def handle_client(client_socket):
MAX_RECV_BUFFER = 1024
allowed_commands = ["ls, cd, ls -l"]
recv_size = 1
while recv_size:
data_buffer = client_socket.recv(MAX_RECV_BUFFER)
command = data_buffer.decode("utf-8")
if not data_buffer:
print("Client just disconected")
break
recv_size = len(data_buffer)
if command in allowed_commands:
response = run_command(commad)
client_socket.send(response.encode("utf-8"))
data_buffer = ""
def init_server(server_address, reuseAddr=True):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
server_socket.bind(server_address)
except socket.error as serr:
print(str(serr))
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if hasattr(socket, "SO_REUSEPORT"):
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
server_socket.listen(5)
print("Server listen at {}:{}".format(server_address[0], server_address[1]))
try:
while True:
client_socket, client_address = server_socket.accept()
print("Client has connected {}:{}".format(client_address[0], client_address[1]))
handle_client(client_socket)
except KeyboardInterrupt as kerr:
print("Server is closing...")
client_socket.close()
server_socket.close()
def run_command(commad):
try:
output = subprocess.check_output(commad, stderr=subprocess.STDOUT,
shell=True)
except OSError as oserr:
return output
if __name__ == "__main__":
init_server(("127.0.0.1",8080))
CLIENT
import socket
def init_client(server_address):
connected = True
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Connecting {} to server ...'.format(server_address))
client_socket.connect(server_address)
while connected:
# allowed__commands = ['ls, cd, ls-l']
try:
if server_address[0] == '127.0.0.1':
message = input('\nlocalhost#localhost' + '>> ')
else:
message = input(server_address[0] + '#' + server_address[1] +
'>> \n')
print('Sending message: {}'.format(message))
client_socket.sendall(message.encode('utf-8'))
recv_data(client_socket)
except IOError as e:
print('Error: {}'.format(e))
except Exception as e:
print('Other error: {}'.format(e))
except KeyboardInterrupt:
connected = False
def recv_data(client_socket):
recv_size = 1
MAX_RECV_BUFFER = 1024
while recv_size:
data_buffer = client_socket.recv(MAX_RECV_BUFFER)
message = data_buffer.decode('utf-8')
print('Received data: '.format(message))
if not data_buffer:
break
recv_size += len(data_buffer)
data_buffer = ''
client_socket.close()
if __name__ == '__main__':
init_client(('127.0.0.1', 8080))
Related
i am trying to implement a TLS secured socket server in python, and i want multiple clients to connect to the server and talk to each other,
what i would like to do is that each client connecting can receive messages sent by other clients also,
Server code:
import socket
import threading
HEADER = 64
PORT = 5050
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} connected.")
connected = True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
print(f"[{addr}] {msg}")
conn.send("Msg received".encode(FORMAT))
conn.close()
def start():
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print("[STARTING] server is starting ...")
start()
Client Code:
import socket
HEADER = 64
PORT = 5050
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
SERVER = "192.168.1.141"
ADDR = (SERVER, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
def send(msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
client.send(send_length)
client.send(message)
print(client.recv(2048).decode(FORMAT))
send(input('[Send a Message]: '))
send(DISCONNECT_MESSAGE)
where can i add the TLS in this?:/
if something isn't right please inform me :)
---------------------EDIT------------------------------
SERVER:
import socket
import select
HEADER_LENGTH = 10
IP = "127.0.0.1"
PORT = 1234
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((IP, PORT))
server_socket.listen(5)
sockets_list = [server_socket]
clients = {}
def receive_message(client_socket):
try:
message_header = client_socket.recv(HEADER_LENGTH)
if not len(message_header):
return False
message_length = int(message_header.decode('utf-8').strip())
return {"header": message_header, "data": client_socket.recv(message_length)}
except:
return False
while True:
read_sockets, _, exception_sockets = select.select(
sockets_list, [], sockets_list)
for notified_socket in read_sockets:
if notified_socket == server_socket:
client_socket, client_address = server_socket.accept()
user = receive_message(client_socket)
if user is False:
continue
sockets_list.append(client_socket)
clients[client_socket] = user
print(
f"Accepted new connection from {client_address[0]}:{client_address[1]} username: {user['data'].decode('utf-8')}")
else:
message = receive_message(notified_socket)
if message is False:
print(
f"closed connection from {clients[notified_socket]['data'].decode('utf-8')}")
sockets_list.remove(notified_socket)
del clients[notified_socket]
continue
user = clients[notified_socket]
print(
f"Received message from {user['data'].decode('utf-8')}: {message['data'].decode('utf-8')}")
for client_socket in clients:
if client_socket != notified_socket:
client_socket.send(
user['header'] + user['data'] + message['header'] + message['data'])
for notified_socket in exception_sockets:
sockets_list.remove(notified_socket)
del clients[notified_socket]
CLIENT:
from http import client
import socket
import select
import errno
import sys
import threading
HEADER_LENGTH = 10
IP = '127.0.0.1'
PORT = 1234
my_username = input("Username: ")
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))
client_socket.setblocking(False)
username = my_username.encode('utf-8')
username_header = f"{len(username):<{HEADER_LENGTH}}".encode('utf-8')
client_socket.send(username_header + username)
def send_message():
message = input(f"{my_username} > ")
if message:
message = message.encode('utf-8')
message_header = f"{len(message):<{HEADER_LENGTH}}".encode('utf-8')
client_socket.send(message_header + message)
while True:
thread = threading.Thread(target=send_message)
thread.start()
try:
while True:
# receive things
username_header = client_socket.recv(HEADER_LENGTH)
if not len(username_header):
print("connection closed by the server")
sys.exit()
username_length = int(username_header.decode('utf-8').strip())
username = client_socket.recv(username_length).decode('utf-8')
message_header = client_socket.recv(HEADER_LENGTH)
message_length = int(message_header.decode('utf-8').strip())
message = client_socket.recv(message_length).decode('utf-8')
print(f"{username} > {message}")
except IOError as e:
if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
print('Reading error', str(e))
sys.exit()
continue
except Exception as e:
print('General error', str(e))
sys.exit()
unfortunately, i cant seem to get the buffer to work right , other clients only receive other clients input when they send messages, so the output is always unordered correctly.
how to use ping/pong for checking the message is delivered to server or not and receive a pong after sucessfull delivery of message in the below code.
I found this code from this link
https://www.positronx.io/create-socket-server-with-multiple-clients-in-python/
server-side.py
import socket
from _thread import *
ServerSideSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ServerSideSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
host = '127.0.0.1'
port = 3040
ThreadCount = 0
try:
ServerSideSocket.bind((host, port))
except socket.error as e:
print(str(e))
print('Socket is listening..')
ServerSideSocket.listen(5)
def multi_threaded_client(connection):
connection.send(str.encode('Server is working:'))
while True:
data = connection.recv(2048)
print(data)
response = 'Server message: ' + data.decode('utf-8')
if not data:
break
connection.sendall(str.encode(response))
connection.close()
while True:
Client, address = ServerSideSocket.accept()
print('Connected to: ' + address[0] + ':' + str(address[1]))
start_new_thread(multi_threaded_client, (Client, ))
ThreadCount += 1
print('Thread Number: ' + str(ThreadCount))
ServerSideSocket.close()
client-side.py
import socket
ClientMultiSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '172.0.0.1'
port = 3040
print('Waiting for connection response')
try:
ClientMultiSocket.connect((host, port))
except socket.error as e:
print(str(e))
res = ClientMultiSocket.recv(1024)
while True:
Input = input('Hey there: ')
ClientMultiSocket.send(str.encode(Input))
res = ClientMultiSocket.recv(1024)
print(res.decode('utf-8'))
ClientMultiSocket.close()
I'm trying to have multiple clients connect to a server socket and transfer data between them, however I want to limit the number of connections that can be made to the server/ number of client processes to 3. How can I do this?
server:
import socket
from _thread import *
PORT = 5050
HOST = socket.gethostbyname(socket.gethostname())
ADDR = (HOST, PORT)
ThreadCount = 0
tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
tcp.bind(ADDR)
except socket.error as e:
print(str(e))
print("Awaiting connection")
tcp.listen(5)
def threaded_client(connection):
connection.send(str.encode('Welcome to sv'))
while True:
data = connection.recv(2048)
reply = 'Server returns: ' + data.decode('utf-8')
if not data:
break
connection.sendall(str.encode(reply))
connection.close()
while True:
Client, address = tcp.accept()
print('Connected to: ' + address[0] + ':' + str(address[1]))
start_new_thread(threaded_client, (Client, ))
ThreadCount += 1
print('Number of threads: ' + str(ThreadCount))
ServerSocket.close()
client:
import socket
Client = socket.socket(socket.AF_INET, socket. SOCK_STREAM)
PORT = 5050
HOST = socket.gethostbyname(socket.gethostname())
ADDR = (HOST, PORT)
print('Awaiting connection')
try:
Client.connect(ADDR)
except socket.error as e:
print(str(e))
Response = Client.recv(1024)
while True:
Input = input('Sends Info: ')
Client.send(str.encode(Input))
Response = Client.recv(1024)
print(Response.decode('utf-8'))
Cliente.close()
I am making server-client communication in python using sockets and threading module. I connect client to server, send some data, receive some data, but the problem is, I can send only two messages. After those, the server is not reciving my packets. Can someone tell me what's wrong? Thanks in advance.
Server.py:
import socket
from threading import Thread
class Server:
def __init__(self):
self.host = '127.0.0.1'
self.port = 9999
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.host, self.port))
self.server.listen(5)
self.threads = []
self.listen_for_clients()
def listen_for_clients(self):
print('Listening...')
while True:
client, addr = self.server.accept()
print('Accepted Connection from: '+str(addr[0])+':'+str(addr[1]))
self.threads.append(Thread(target=self.handle_client, args=(client, addr)))
for thread in self.threads:
thread.start()
def handle_client(self, client_socket, address):
client_socket.send('Welcome to server'.encode())
size = 1024
while True:
message = client_socket.recv(size)
if message.decode() == 'q^':
print('Received request for exit from: '+str(address[0])+':'+str(address[1]))
break
else:
print('Received: '+message.decode()+' from: '+str(address[0])+':'+str(address[1]))
client_socket.send('Received request for exit. Deleted from server threads'.encode())
client_socket.close()
if __name__=="__main__":
main = Server()
Client.py
import socket
import sys, time
def main():
target_host = '127.0.0.1'
target_port = 9999
try:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print('Could not create a socket')
time.sleep(1)
sys.exit()
try:
client.connect((target_host, target_port))
except socket.error:
print('Could not connect to server')
time.sleep(1)
sys.exit()
while True:
data = input()
client.send(data.encode())
message = client.recv(4096)
print('[+] Received: '+ message.decode())
main()
You have to send exit message 'q^' to client too to close client.
Warning:
Using Unicode as encoding for string is not recommended in socket. A partial Unicode character may be received in server/client resulting in UnicodeDecodeError being raised.
Code for server using threads is:
server.py:
import socket
from threading import Thread
class Server:
def __init__(self, host, port):
self.host = host
self.port = port
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.host, self.port))
self.server.listen(5)
def listen_for_clients(self):
print('Listening...')
while True:
client, addr = self.server.accept()
print(
'Accepted Connection from: ' + str(addr[0]) + ':' + str(addr[1])
)
Thread(target=self.handle_client, args=(client, addr)).start()
def handle_client(self, client_socket, address):
size = 1024
while True:
try:
data = client_socket.recv(size)
if 'q^' in data.decode():
print('Received request for exit from: ' + str(
address[0]) + ':' + str(address[1]))
break
else:
# send getting after receiving from client
client_socket.sendall('Welcome to server'.encode())
print('Received: ' + data.decode() + ' from: ' + str(
address[0]) + ':' + str(address[1]))
except socket.error:
client_socket.close()
return False
client_socket.sendall(
'Received request for exit. Deleted from server threads'.encode()
)
# send quit message to client too
client_socket.sendall(
'q^'.encode()
)
client_socket.close()
if __name__ == "__main__":
host = '127.0.0.1'
port = 9999
main = Server(host, port)
# start listening for clients
main.listen_for_clients()
client.py:
import socket
import sys, time
def main():
target_host = '127.0.0.1'
target_port = 9999
try:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print('Could not create a socket')
time.sleep(1)
sys.exit()
try:
client.connect((target_host, target_port))
except socket.error:
print('Could not connect to server')
time.sleep(1)
sys.exit()
online = True
while online:
data = input()
client.sendall(data.encode())
while True:
message = client.recv(4096)
if 'q^' in message.decode():
client.close()
online = False
break
print('[+] Received: ' + message.decode())
break # stop receiving
# start client
main()
I have a simpletcp example:
import socket
import time
TCP_IP = '127.0.0.1'
TCP_PORT = 81
BUFFER_SIZE = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
while True:
s.send(bytes('hello', 'UTF-8'))
time.sleep(1)
s.close()
How can I detect, if I lost the connection to the server, and how can I safely reconnect then?
Is it necessary to wait for answer to the server?
UPDATE:
import socket
import time
TCP_IP = '127.0.0.1'
TCP_PORT = 81
BUFFER_SIZE = 1024
def reconnect():
toBreak = False
while True:
s.close()
try:
s.connect((TCP_IP, TCP_PORT))
toBreak = True
except:
print ("except")
if toBreak:
break
time.sleep(1)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
while True:
try:
s.send(bytes('hello', 'UTF-8'))
print ("sent hello")
except socket.error as e:
reconnect()
time.sleep(1)
s.close()
If I break the connection, it raises an error (does not really matter what), and goes to the
reconnect loop. But after I restore the connection, the connect gives back this error:
OSError: [WinError 10038] An operation was attempted on something that is not a socket
If I restart the script, which calls the same s.connect((TCP_IP, TCP_PORT)), it works fine.
You'll get a socket.error:[Errno 104] Connection reset by peer exception (aka ECONNRESET) on any call to send() or recv() if the connection has been lost or disconnected. So to detect that, just catch that exception:
while True:
try:
s.send(bytes('hello', 'UTF-8'))
except socket.error, e:
if e.errno == errno.ECONNRESET:
# Handle disconnection -- close & reopen socket etc.
else:
# Other error, re-raise
raise
time.sleep(1)
Use a new socket when you attempt to reconnect.
def connect():
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
return s.makefile('w')
except socket.error as e:
log("socket error {} reconnecting".format(e))
time.sleep(5)
dest = connect()
while True:
line = p.stdout.readline()
try:
dest.write(line)
dest.flush()
except socket.error as e:
log("socket error {} reconnecting".format(e))
dest = connect()
Can you try that (I think that you does'not try socket.SO_REUSEADDR):
def open_connection():
data0=''
try:
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Connect the socket to the port where the server is listening
server_address = ('192.168.0.100', 8000)
sock.settimeout(10) # TimeOut 5 secunde
while True:
try:
sock.connect(server_address)
message = 'new connection'
sock.sendall(message)
# Look for the response
amount_received = 0
data0=sock.recv(1024)
amount_received = len(data0)
return
finally:
wNET = 0
pass
except:
sock.close()
time.sleep(60)
del data0
This is the code based on thread. The main tip is that the received buffer cannot be none, if the socket is connected.
import time
import socket
import threading
def connect():
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.settimeout(60)
return s
except socket.error as e:
print("socket error {} reconnecting".format(e))
time.sleep(5)
soc = connect()
def runSocket():
global soc
while True:
try:
recBuf = soc.recv(64)
if recBuf == b'': #remote server disconnect
soc = connect()
else:
print(recBuf)
except socket.timeout:
print("Timeout")
except Exception as e:
print("other socket error {}".format(e))
soc = connect()
socketThread = threading.Thread(target=runSocket)
socketThread.start()