I want my server to send the string "con-res 0xFE" to reset the server if it has been more than 4 seconds since a new message was sent by the client.
I have tried to puzzle around with time.time() but in the end I can't figure out how to register a time for each message it self.
Client:
import socket
# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('localhost', 12000)
number_of_packages = 0;
try:
while True:
message = input("Write something: ")
# Send data
sent = sock.sendto(message.encode(), server_address)
number_of_packages +=1
if (number_of_packages > 25):
print("Too many packages - closing socket")
socket.close()
# Receive response
data, server = sock.recvfrom(4096)
print('client received: ', data.decode())
if data.decode()=="con-res 0xFE":
print("conn reset!")
sent = sock.sendto("con-res 0xFFDDDDD".encode(), server_address)
finally:
sock.close()
My server:
# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Bind the socket to the port
server_address = ('localhost', 12000)
sock.bind(server_address)
count_message = 0
while True:
data, address = sock.recvfrom(4096)
#check 4 seconds since last message
if data:
start_time = time.time()
sent = sock.sendto("ok".encode(), address)
The above code incidents might be wrong as I had difficulties make sure it looked as code here on Stackoverflow. However the above code is working as it should.
Related
I want to customize a addon to filter the specified HOST request, and can send some socket messages unidirectionally after each successful filtering, but every time receiving a socket message in another process will generate a delay of about 0.15s.
Is there a better way please, or where is the problem with my code?
System Information:
Mitmproxy: 6.0.2
List item
Python: 3.8.0
Platform: macOS-12.2.1
The main code of the addon:
class MyAddon:
#script.concurrent
def request(self, flow: http.HTTPFlow):
...
#script.concurrent
def response(self, flow: http.HTTPFlow):
msg = ... #Create a message
if flow.request.host in HOST_LIST:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.connect((HOST, PORT))
s.send(msg)
This is the server process code:
class Server:
def __init__(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
port = 9999
self.sock.bind(('127.0.0.1', port))
self.sock.listen(10)
self.sever_th = threading.Thread(target=self.tcp_server)
self.sever_th.start()
def tcp_server(self):
while True:
t0 = time.time()
conn, addr = self.sock.accept() #There is a delay of about 0.15s
print('%0.5f' % (time.time() - t0))
with conn:
buff = b''
while True:
data = conn.recv(1024)
if data == b'':
print(buff)
break
else:
buff += data
if __name__ == "__main__":
server = Server()
I have tried sending messages using one socket, but the delay effect is still the same.
I use the Socket to send multiple groups of the same message without the Addon, and there is no such high delay.The bytes of each message sent are about 600 Bytes.
A quite basic problem, but I can't find my mistake. I bascially used this tutorial code to implement my own client-server program: Client sends some data, the server displays it (instead of echoing data like in the tutorial)
The echoing tutorial code works, but my adjusted code to print data on the server doesn't. I added some delimiter mechanism to detect the entire message. My code:
Server.py:
class ThreadedServer:
def __init__(self, host, port):
self.host = host
self.port = port
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind((self.host, self.port))
print("Server bound on Port "+str(port))
def listen(self):
self.sock.listen(5)
while True:
print("Waiting for incoming connections...")
client, address = self.sock.accept()
client.settimeout(60)
print("Starting Working thread.")
threading.Thread(target=self.listenToClientDelimiter, args=(client, address)).start()
def listenToClientDelimiter(self, client, address):
print("Connect to client "+address)
length = None
buffer = ""
while True:
data = client.recv(1024)
print("Received raw data: "+str(data))
if not data:
break # connection closed
buffer += data
while True:
if length is None:
if LENGTH_DELIMITER not in buffer:
break # delimiter not found, wait for next data package
length_str, _, buffer = buffer.partition(LENGTH_DELIMITER)
length = int(length_str)
if len(buffer) < length:
break # wait until full length got received before we proceed
message = buffer[:length]
buffer = buffer[length:]
length = None
# PROCESS MESSAGE HERE
print(message)
client.close()
if __name__ == "__main__":
ThreadedServer('', 65432).listen()
Client.py:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect(("127.0.0.1", 65432))
connect_user_cmd = "18:CONNECT_USER;Peter"
print("Trying to send data: "+connect_user_cmd.decode())
print(s.send(connect_user_cmd))
I run the server, then the client. The output from the server:
Server bound on Port 65432
Waiting for incoming connections...
As you see, I expect some log messages and of course my sent message. The client outputs this:
Trying to send data: 18:CONNECT_USER;Peter
21
Process finished with exit code 0
This gets outputted from the client even when I don't start the server. The weird thing is that the echoing part did indeed work. Could someone hint me into the right direction? Thank you!
I would like to write a very simple rock-paper-scissors game in Python. I would like to have 1 server and 2 clients. After connecting to the server, the server should send a message to each client to choose (r/p/s). After this, each client should send back their choice and the server then decides about the winner, and then it informs the clients about the winner.
This is what I have so far:
This is the server.py
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 server socket thread started for " + ip + ":" + str(port))
def run(self):
while True:
data = conn.recv(1024).decode()
print("Server received data:", data)
MESSAGE = input("Server response: ")
if MESSAGE == 'exit':
break
conn.send(MESSAGE.encode())
TCP_IP = '0.0.0.0'
TCP_PORT = 2004
BUFFER_SIZE = 1024
tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpServer.bind((TCP_IP, TCP_PORT))
threads = []
while True:
tcpServer.listen(4)
print("Multithreaded Python server : Waiting for connections from TCP clients...")
(conn, (ip, port)) = tcpServer.accept()
newthread = ClientThread(ip, port)
newthread.start()
threads.append(newthread)
for t in threads:
t.join()
This is clientA.py:
import socket
host = socket.gethostname()
port = 2004
BUFFER_SIZE = 1024
MESSAGE = input("tcpClientA:")
tcpClientA = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpClientA.connect((host, port))
while MESSAGE != 'exit':
tcpClientA.send(MESSAGE.encode())
data = tcpClientA.recv(BUFFER_SIZE).decode()
print(" ClientA received data:", data)
MESSAGE = input("tcpClientA:")
tcpClientA.close()
This is clientB.py:
import socket
host = socket.gethostname()
port = 2004
BUFFER_SIZE = 1024
MESSAGE = input("tcpClientB:")
tcpClientB = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpClientB.connect((host, port))
while MESSAGE != 'exit':
tcpClientB.send(MESSAGE.encode())
data = tcpClientB.recv(BUFFER_SIZE).decode()
print(" ClientB received data:", data)
MESSAGE = input("tcpClientB:")
tcpClientB.close()
In this code, however, I can only send messages to the server and it can respond. Unfortunately, I don't know, how I can send messages to a specific client in this case. (I need to send different messages to the winner and to the loser).
First, this is not a trivial exercise and it will require a decent understanding of how threads work and how to work with them in Python in particular. What you seem to be missing at the moment is a way of orchestrating the communication from the 2 clients and of keeping track of what each client played so you can decide which client wins.
What currently happens is that when tcpClientA.connect((host, port)) runs on client A, (conn, (ip, port)) = tcpServer.accept() gets unblocked in the server. This creates a new instance of your ClientThread class and the new thread starts listening for data to be sent by client A on the connection. When client B runs, the same happens and you now have 2 threads running and listening for data but no way of knowing which plays what.
What I would suggest is to introduce a new class that will represent the game itself. That class will get the messages from both client and respond to each accordingly. What you will also need is a way of waiting for both clients to have played their turn before being able to decide who wins and what to send to each.
One way to do it would be with Barrier objects.
I am building a simple network chat in Python using UDP, however, when I run the server code on one machine and the client on another, no message is received by the server and no message is sent back to the client by the server script. Here is my code:
Server:
import socket, sys
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', 9997)) #need higher port
while True:
x = raw_input("Enter your message: ")
sent = sock.sendto(x, ('', 9997))
data, address = sock.recvfrom(4096)
print data, " ", address
sock.close()
Client:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
print "Waiting to receive"
data, server = sock.recvfrom(4096)
print data
x = raw_input("Enter message: ")
sent = sock.sendto(x, server)
sock.close()
Does anyone know what I am doing wrong here? Is is possible that code is fine, but the UDP is not reliable enough and is dropping the message?
As I said, since your code seems a little unclear (to me, at least), I'm posting you a very similar working example.
Here's the Server:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('localhost', 1932)
sock.bind(server_address)
BUFFER_SIZE = 4096
try:
while True:
data, address = sock.recvfrom(BUFFER_SIZE)
print "Client sends: ", data
reply = raw_input("Your response:\n")
sock.sendto(reply,address)
except KeyboardInterrupt:
sock.close()
The server creates a socket and binds it to its address and the port it's listening to, 1932 in our case. He waits for an incoming message, asks for a reply, then sends it back to the sender.
Here's the Client:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client_address = ('localhost', 1931)
server_address = ('localhost', 1932)
sock.bind(client_address)
BUFFER_SIZE = 4096
try:
first_msg = raw_input("Your first message:\n")
sock.sendto(first_msg,server_address)
while True:
data, address = sock.recvfrom(BUFFER_SIZE)
print "Client sends: ", data
reply = raw_input("Your response:\n")
sock.sendto(reply,address)
except KeyboardInterrupt:
sock.close()
It's very similar to the server, the only difference is that it sends a message before the while loop, in order to start the conversation. Then it just enters the receive/reply loop, just as the server does. It has the server address too, that is different (different port, since I'm on localhost)
The try/catch block is here just to close gracefully the whole process.
I used localhost and different ports on my computer and tested it, and it works. You should just change the addresses to get it working over LAN, and you could keep the same port if the addresses are different, it should work.
So I have created a socket program for both client and server as a basic chat. I made it so the server accepts multiple clients with threading, so that is not the problem. I am having trouble sending messages to each client that is connected to the server. I am not trying to have the server send a message it created but rather have client1 sending a message to client2 by going through the server. For some reason it will only send it back to client1.
For example, client1 will say hello and the server will send the same message back to client1 but nothing to client2. I fixed this slightly by making sure the client doesn't receive its own message but client2 is still not receiving the message from the client1.
Any help will be appreciated.
I have tried multiple changes and nothing seems to work. You can look at my code for specifics on how I did things but ask if there are any questions.
Also, there is a question where someone has asked that is similar and I thought it would give me an answer but the responses stopped going through and a solution was never fully given, so please don't just refer me to that question. that is located here: Python 3: Socket server send to multiple clients with sendto() function.
Here's the code:
CLIENT:
import socket
import sys
import thread
#Create a socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#Enter username to identify self to others
name = raw_input("Enter username: ") + ": "
#Connect socket to ip and port
host = socket.gethostname()
#host = '192.168.1.10'
server_address = (host, 4441)
sock.connect(server_address)
#function waiting to receive and print a message
def receive(nothing):
while True:
data = sock.recv(1024)
if message != data:
print data
# Send messages
while True:
#arbitrary variable allowing us to have a thread
nothing = (0, 1)
message = name + raw_input("> ")
sock.sendall(message)
#thread to receive a message
thread.start_new_thread(receive, (nothing,))
SERVER:
import socket
import sys
import thread
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the port
host = socket.gethostname()
server_address = (host, 4441)
sock.bind(server_address)
#Listen for incoming connections
sock.listen(5)
print "Waiting for connection..."
#Variable for the number of connections
numbOfConn = 0
#Name of list used for connections
addressList = []
#Function that continuosly searches for connections
def clients(connection, addressList):
while True:
message = connection.recv(1024)
print message
#connection.sendall(message)
#for loop to send message to each
for i in range(0,numbOfConn - 1):
connection.sendto(message, addressList[i])
connection.close()
while True:
#accept a connection
connection, address = sock.accept()
print 'Got connection from', address
numbOfConn += 1
addressList.append((address))
#Thread that calls the function: clients and stores them in a tuple called connection
thread.start_new_thread(clients, (connection, addressList))
sock.close()
Please help me if you can!
EDIT:
I was able to fix it to a certain extent. It is still a little buggy but I am able to send messages back and forth now. I needed to specify the connection socket as well as the address. Here's the updated code:
SERVER
import socket
import sys
import thread
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the port
host = socket.gethostname()
server_address = (host, 4441)
sock.bind(server_address)
#Listen for incoming connections
sock.listen(5)
print "Waiting for connection..."
#Variable for the number of connections
numbOfConn = 0
#Name of list used for connections
addressList = []
connectionList = []
#Function that continuosly searches for connections
def clients(connectionList, addressList):
while True:
for j in range(0,numbOfConn):
message = connectionList[j].recv(1024)
print message
#for loop to send message to each
for i in range(0,numbOfConn):
connectionList[i].sendto(message, addressList[i])
connection.close()
while True:
#accept a connection
connection, address = sock.accept()
print 'Got connection from', address
numbOfConn += 1
addressList.append((address))
connectionList.append((connection))
#Thread that calls the function: clients and stores them in a tuple called connection
thread.start_new_thread(clients, (connectionList, addressList))
sock.close()