Python socket exploiting client address and port for response - python

(I have the following code in which I would like to implement a server-side application and to send clients a response:
class client(Thread):
def __init__(self, socket, address):
Thread.__init__(self)
self.sock = socket
self.addr = address
self.start()
def run(self):
request = ''
while 1:
data = self.sock.recv(1024).decode() # The program hangs here with large message
if not data:
break
request += data
print(request, self.addr[1], self.addr[0]))
message = "test"
self.sock.send(message.encode())
def init_server():
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind((host, int(port)))
serversocket.listen(5)
while 1:
clients, address = serversocket.accept()
client(clients, address)
return
Now I write a simple client:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('localhost', 8000))
client_socket.send(message)
request = ''
while 1:
data = client_socket.recv(2048).decode()
if not data:
break
request += data
print(request)
client_socket.close()
The problem now is that the server hangs in recv with a large message. How can I solve it?

Your client socket and server socket are different sockets.
You can get server info using the serversocket object the same way you try self.sock.
I would recommend parsing serversocket as a third argument into your client class, and then using it within the class like so:
class client(Thread):
def __init__(self, socket, address, server):
Thread.__init__(self)
self.sock = socket
self.addr = address
self.server = server
self.start()
def run(self):
request=''
while 1:
data=self.sock.recv(1024).decode()
if not data:
break
request+=data
print(request, self.server.getsockname()[1], self.server.getsockname()[0]))
def init_server():
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind((host, int(port)))
serversocket.listen(5)
while 1:
clients, address = serversocket.accept()
client(clients, address, serversocket)
return
That should output the server information.
If you wanted the client information, it's parsed in the 'address' as a tuple, you can see the remote IP address and the socket port used to communicate on (not the open port).

Related

How do I send a socket username and a socket message then sending it to discord using webhooks

I've been trying to send username and message data to a discord webhook but have been getting back this
<main.ChatServer object at 0x00000245274EB760>: <socket.socket fd=1068, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 10319), raddr=('127.0.0.1', 51363)>.
Here is the code:
#imports
import socket
import threading
from discord_webhook import DiscordWebhook
class ChatServer:
clients_list = []
last_received_message = ""
def __init__(self):
self.server_socket = None
self.create_listening_server()
#listen for incoming connection
def create_listening_server(self):
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #create a socket using TCP port and ipv4
local_ip = '127.0.0.1'
local_port = 10319
# this will allow you to immediately restart a TCP server
self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# this makes the server listen to requests coming from other computers on the network
self.server_socket.bind((local_ip, local_port))
print("Listening for incoming messages..")
self.server_socket.listen(5) #listen for incoming connections / max 5 clients
self.receive_messages_in_a_new_thread()
#fun to receive new msgs
def receive_messages(self, so):
while True:
incoming_buffer = so.recv(256) #initialize the buffer
if not incoming_buffer:
break
self.last_received_message = incoming_buffer.decode('utf-8')
self.broadcast_to_all_clients(so) # send to all clients
webhook = DiscordWebhook(url='https://discord.com/api/webhooks/1053657076607496192/DXuj0B7fcJwe8nGEQwkxOqFxObB_hTdSfjzct3WoyPX94OFjJ91dM-2f6M93EshcYgn2', content={
"username": f"{self}",
"content": f"{so}"
})
response = webhook.execute()
so.close()
#broadcast the message to all clients
def broadcast_to_all_clients(self, senders_socket):
for client in self.clients_list:
socket, (ip, port) = client
if socket is not senders_socket:
socket.sendall(self.last_received_message.encode('utf-8'))
def receive_messages_in_a_new_thread(self):
while True:
client = so, (ip, port) = self.server_socket.accept()
self.add_to_clients_list(client)
print('Connected to ', ip, ':', str(port))
t = threading.Thread(target=self.receive_messages, args=(so,))
t.start()
#add a new client
def add_to_clients_list(self, client):
if client not in self.clients_list:
self.clients_list.append(client)
if __name__ == "__main__":
ChatServer()

Adding a whitelist to a python socket server

I am wondering how I would make a whitelist, or a list of allowed IPs. There is someone trying to join my server, and he uses a VPN to hide his IP and change it. Please help me, it’s shutting down my server every time he does this.
My code is:
import socket
import threading
class ChatServer:
clients_list = []
last_received_message = ""
def __init__(self):
self.server_socket = None
self.create_listening_server()
def create_listening_server(self):
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
local_ip = '127.0.0.1'
local_port = 10319
# this will allow you to immediately restart a TCP server
self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# this makes the server listen to requests coming from other computers on the network
self.server_socket.bind((local_ip, local_port))
print("Listening for incoming messages..")
self.server_socket.listen(5)
self.receive_messages_in_a_new_thread()
def receive_messages(self, so):
while True:
incoming_buffer = so.recv(256)
if not incoming_buffer:
break
self.last_received_message = incoming_buffer.decode('utf-8')
self.broadcast_to_all_clients(so) # send to all clients
so.close()
def broadcast_to_all_clients(self, senders_socket):
for client in self.clients_list:
socket, (ip, port) = client
if socket is not senders_socket:
socket.sendall(self.last_received_message.encode('utf-8'))
def receive_messages_in_a_new_thread(self):
while True:
client = so, (ip, port) = self.server_socket.accept()
self.add_to_clients_list(client)
print('Connected to ', ip, ':', str(port))
t = threading.Thread(target=self.receive_messages, args=(so,))
t.start()
def add_to_clients_list(self, client):
if client not in self.clients_list:
self.clients_list.append(client)
if __name__ == "__main__":
ChatServer()
In receive_messages_in_a_new_thread(self), I am getting an IP of the client. I tried using:
whitelist = [“client-ip”, “client-ip”]
if ip not in whitelist:
so.close()
else:
pass
But it still lets other IPs in. I even tried a blacklist:
blacklist = [“client-ip”, “client-ip”]
if ip in blacklist:
so.close()
else:
pass
What am I missing? Is there another thing that I should know about?

How to close Python socket server when all of its multiple clients close the connection?

I have made a multithreaded Python socket server.
It supports multiple socket client connections.
My code is:
import socket
from _thread import *
def multi_threaded_client(connection):
response = ''
while True:
data = connection.recv(10000000)
response += data.decode('utf-8')
if not data:
print(response)
break
connection.send(bytes(some_function_name(response), "utf-8"))
connection.close()
class socketserver:
def __init__(self, address='', port=9090):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.address = address
self.port = port
self.sock.bind((self.address, self.port))
self.cummdata = ''
def recvmsg(self):
self.sock.listen(65535)
self.conn, self.addr = self.sock.accept()
print('connected to', self.addr)
self.cummdata = ''
start_new_thread(multi_threaded_client, (self.conn, ))
return self.cummdata
def __del__(self):
self.sock.close()
serv = socketserver('127.0.0.1', 9090)
print('Socket Created at {}. Waiting for client..'.format(serv.sock.getsockname()))
while True:
msg = serv.recvmsg()
I also want the server to detect if any new client is connected to /disconnected from it.
Once all the clients are disconnected from it, I want the server to be closed on its own.
I could not figure this out

Send TCP message at random time to one of several clients in python

I am trying to send a TCP message at random time, depending on when the user input is received, to one of several clients from which I am receiving data on a thread for each client.
I am storing the IP of each client inside an SQL database and I decide to which IP i want to send data based on user input. How should I approach sending a message to a specific client ? I don't know how I can gain access over each socket connection and use it to send messages.
Any device, links of examples, or code snippets are greatly welcome.
This is the server code that I have so far :
import socket
import threading
from database import Database
d = Database()
def Read_RFID_tag():
while True:
receiveID = raw_input("tag input : ")
d.updateTable(receiveID, 1);
print(receiveID)
class ThreadedServer(object):
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))
def listen(self):
self.sock.listen(5)
while True:
client, address = self.sock.accept()
print("new client")
client.settimeout(60)
threading.Thread(target = self.listenToClient,args = (client,address)).start()
def listenToClient(self, client, address):
size = 1024
while True:
query_result = d.existsWashedInTable(address)
try:
data = client.recv(size)
if data:
# Set the response to echo back the received data
print(data)
response = data
d.addEntryToTable(response,address, 0)
client.send(response)
else:
raise error('Client disconnected')
except:
client.close()
return False
if __name__ == "__main__":
port_num = 5005
d.createTable()
threading.Thread(target=Read_RFID_tag).start()
ThreadedServer('',port_num).listen()

Python, client-server application, does not connect

For some reason, the next elementary program connects the client to the server only from the second time. And so every time after restarting the server. Can someone explain the reason for this behavior and how to solve this problem? Maybe it's because asyncore is only used on the server side? (Windows 7, Python 3) Thank you in advance!
Сlient:
import socket
sock = socket.socket()
host = 'localhost'
port = 8081
tempr = port
sock.connect((host,port))
Server:
import asyncore
import socket
import time
class EchoHandler(asyncore.dispatcher_with_send):
def handle_read(self):
data = self.recv(1024)
class EchoServer(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind((host, port))
self.listen(2)
def handle_accept(self):
pair = self.accept()
if pair is not None:
sock, addr = pair
print ('Incoming connection from %s' % repr(addr))
handler = EchoHandler(sock)
def main():
host = 'localhost'
port = 8081
server = EchoServer(host, port)
print ('Server %s running'% port)
asyncore.loop()
if __name__ == '__main__':
main()
The whole point of socket is to send() and recv() (receive) data between client and server. You must send some data (even an empty string must be sent) to server after connecting to server and server may return some data to client and/or just close connection.
my_client.py
import socket
sock = socket.socket()
sock.connect(('localhost', 8081))
sock.send(b'data from client')
print(sock.recv(32))
sock.close()
my_server.py
import asyncore
import socket
import time
class EchoHandler(asyncore.dispatcher_with_send):
def handle_read(self):
data = self.recv(1024)
print('data from client', data)
self.send(b'data from server')
self.close()
class EchoServer(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind((host, port))
self.listen(2)
def handle_accept(self):
pair = self.accept()
if pair is not None:
sock, addr = pair
print('Incoming connection from %s' % repr(addr))
handler = EchoHandler(sock)
def main():
host = 'localhost'
port = 8081
server = EchoServer(host, port)
print('Server %s running' % port)
asyncore.loop()
if __name__ == '__main__':
main()
Update:
You do get an error: OSError: [WinError 10038] because you are closing socket in server without reading all data from client. The same is happening in client side too.
In Python documentation it is explicitly stated that these are very basic examples.
Use method sendall() to be sure that all data is sent. Method send() does not guaranty sending of all data.
You must read data from socket with a while loop like this:
my_client.py
import socket
sock = socket.socket()
sock.connect(('localhost', 8081))
sock.sendall(b'data from client')
chunk = b'' # socket.recv returns bytes
data = b'' # defined before to avoid NameError
while True:
chunk = sock.recv(32)
if chunk:
data += chunk
else:
break
print(data)
sock.close()
my_server.py
import asyncore
import socket
import time
class EchoHandler(asyncore.dispatcher_with_send):
def handle_read(self):
chunk = b'' # socket.recv returns bytes
data = b'' # defined before to avoid NameError
while True:
chunk = self.recv(1024)
if chunk:
data += chunk
else:
break
print('data from client', data)
self.sendall(b'data from server')
self.close()
class EchoServer(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind((host, port))
self.listen(2)
def handle_accept(self):
pair = self.accept()
if pair is not None:
sock, addr = pair
print('Incoming connection from %s' % repr(addr))
handler = EchoHandler(sock)
def main():
host = 'localhost'
port = 8081
server = EchoServer(host, port)
print('Server %s running' % port)
asyncore.loop()
if __name__ == '__main__':
main()

Categories

Resources