How to read all data from Python socket.recv()? - python

I'm trying to send mails through smtp protocol in a very simple, basic code.
import socket
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 2525
clientSocket.connect(('localhost', port))
clientSocket.settimeout(5)
helo = 'HELO Me'
clientSocket.send(bytes(helo, 'utf-8'))
response = clientSocket.recv(1024).decode('utf-8')
print(f'Response: {response}')
# this response gets printed to the console
print('Succesfully connected via smtp')
mailFrom = 'MAIL FROM: myemail#gmail.com'
clientSocket.send(bytes(mailFrom, 'utf-8'))
response = clientSocket.recv(1024).decode('utf-8')
print(f'Response: {response}')
# here my program is blocked, and eventually gets a timeout
The problem is when I recieve the response, my, program stops running at the second response. I reckon my recv() function call is wrong, since if I change the first recv() buffersize to let's say 20, it works fine, so I guess there's still some data left in the socket. But how do I read it?

Related

Python UDP socketserver returning empty message

I have a UDP socketserver program that I use to demonstrate how UDP works (code for the server and client are below). I run this on a server, then have the client.py program send a message and receive a reply. I am unfortunately running into an issue that seems to only occur on campus Wifi. On campus wifi, the client does not receive a response.
Troubleshooting with Wireshark shows the issue. For some reason the UDP server is responding with two UDP messages - one empty, and one containing the response message. These messages are recorded in Wireshark as coming in approximately 0.000002 seconds apart. On a wired network, the one with the response consistently comes first, and on Wifi, the empty message consistently comes first. Since the client is waiting for a single messages response, when the empty message returns, the client prints and exits, and the actual response is never seen.
I know I could write the client to listen for both messages and print out whichever one has the data, but I would rather try to figure out what's going on. Why is the socketserver responding with two messages in the first place, and how can I get it to only send one? OR at least to send the data first.
server.py:
import socketserver
class MyUDPRequestHandler(socketserver.DatagramRequestHandler):
def handle(self):
data = self.request[0].strip()
socket = self.request[1]
# just send back the same data, but lower-cased
socket.sendto(data.lower(), self.client_address)
if __name__ == "__main__":
with socketserver.UDPServer(("0.0.0.0", 9091), MyUDPRequestHandler) as server:
server.serve_forever()
client.py:
import socket
HOST, PORT = "localhost", 9091
message = "NOW I AM SHOUTING" # The UDP server will lowercase the message
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(bytes(message + "\n", "utf-8"), (HOST, PORT))
received = str(sock.recv(1024), "utf-8")
print("Sent: {}".format(message))
print("Received: {}".format(received))
I've repeated the problem and it's socketserver. Notice the definition of DatagramRequestHandler below:
class DatagramRequestHandler(BaseRequestHandler):
"""Define self.rfile and self.wfile for datagram sockets."""
def setup(self):
from io import BytesIO
self.packet, self.socket = self.request
self.rfile = BytesIO(self.packet)
self.wfile = BytesIO()
def finish(self):
self.socket.sendto(self.wfile.getvalue(), self.client_address)
The packet is put into a buffer as rfile and should be read from there, then written back to the wfile buffer. finish sends the packet. The handler shouldn't call sendto itself:
import socketserver
class MyUDPRequestHandler(socketserver.DatagramRequestHandler):
def handle(self):
data = self.rfile.read()
self.wfile.write(data.strip().lower())
if __name__ == "__main__":
with socketserver.UDPServer(("0.0.0.0", 9091), MyUDPRequestHandler) as server:
server.serve_forever()
But just using a simple socket as the server works fine too:
import socket
s = socket.socket(type=socket.SOCK_DGRAM)
s.bind(('', 9091))
while True:
data, client = s.recvfrom(2048)
s.sendto(data.strip().lower(), client)
Note that UDP packets are not guaranteed to be delivered or delivered in the same order, so the original code's issue with the two packets changing order isn't surprising.

Python TCP sockets headers

I need to create a communication between a client and a server with TCP. But I'd like to send and work with "headers". So from the client I'd like to send a header "COMMAND1" and the server returns me something.
I have the following code:
Server
import socket
import threading
bind_ip = '0.0.0.0'
bind_port = 9998
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_ip, bind_port))
server.listen(5) # max backlog of connections
print ('Listening on {}:{}'.format(bind_ip, bind_port))
def handle_client_connection(client_socket):
request = client_socket.recv(1024)
print ('Received {}'.format(request))
client_socket.send('Response1!'.encode('utf-8'))
client_socket.close()
while True:
client_sock, address = server.accept()
print ('Accepted connection from {}:{}'.format(address[0], address[1]))
client_handler = threading.Thread(
target=handle_client_connection,
args=(client_sock,) # without comma you'd get a... TypeError: handle_client_connection() argument after * must be a sequence, not _socketobject
)
client_handler.start()
Client
import socket
hostname, sld, tld, port = 'www', 'integralist', 'co.uk', 80
target = '{}.{}.{}'.format(hostname, sld, tld)
# create an ipv4 (AF_INET) socket object using the tcp protocol (SOCK_STREAM)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect the client
# client.connect((target, port))
client.connect(('0.0.0.0', 9998))
# send some data (in this case a HTTP GET request)
client.send('hi'.encode('utf-8'))
# receive the response data (4096 is recommended buffer size)
response = client.recv(4096)
print (response)
Anyone knows the best way to return "Response1!" when the header is "COMMAND1" and "Response2!" when the header is "COMMAND2"?
I can't find examples on how to use headers
EDIT: It doesn't have to be "COMMAND1" or "COMMAND2" it can be a "0" or "1", or anything else.
If you want to add your own header, you just have to:
Make sure your programm finds the start of your message (like, every message beginns "!?&")
Send your own header-data just after the start-symbol of your message.
Maybe mark the end of your message with something or pass a length in your header.
Since TCP will give you a stream of data, it might come to a case, where it just gives you 2 or 3 messages at once. You have to separate these messages by yourself (e.g. by using "?!&" as start of every message).
You can always create your own protocoll as payload of another protocoll. Just as TCP is just payload from the ethernet point of view.
You can do something i have done with my program to accept such headers
Use pickle library to encode a dict headers and send it through socket.
Code will look something like this.
import pickle
def handleSocket(headers:dict):
message = pickle.dumps(headers)
socket.send(message)
For server side, you will be handling it
Gonna initialise the socket recv to 100 kb
def handleReceivedSocket(socket):
message:dict = pickle.loads(socket.recv(102400))
Another way to do this. Is sending a raw json string to the server (just change pickle.dumps,pickle.loads by json.dumps,json.loads
But it will be in raw and less secure.
Last way you can do it is uri encoding. Check w3schools

Custom Python Script for SSL-Strip

"Firts of all this stuff is for my university(a challeng) nothing bad is happening in RL"!
Im not quite familier with phyton but, i give it a trie.
The task is to performe a ssl Stripping attack through a phython script.
The output off the script musst be Username and PW (stdout)
My problem is now:
When i download the ssl strip binarie i see a python script which should include the relevant stuff (sslstrip) but, im not soure where i should start here?
I noticed that the two classes ClientsRequest & Stripping Proxy are essential so they are an the bottom.
My problem is how can i i connect the client request class so that it reads the data from the client ?
Im not sure but this could be the config for the port:8080
(the script must listen on 8080)
# Standard socket stuff:
host = '' # do we need socket.gethostname() ?
port = 8080
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((host, port))
sock.listen(1) # don't queue up any requests
# Loop forever, listening for requests:
while True:
csock, caddr = sock.accept()
print "Connection from: " + `caddr`
req = csock.recv(1024) # get the request, 1kB max
I need a little spark in the right direction.
best regards
Rolento
# Loop forever, listening for requests:
while True:
csock, caddr = sock.accept() #< - this is a blocking call
print "Connection from: " + `caddr`
#you never end up getting to this instruction
req = csock.recv(1024) # get the request, 1kB max
you have some problems
sock.accept will block waiting for a connection ... once you get the connection you print their data and loop right back to the waiting for connection ... when in reality you want to do something with that connection
while True:
csock, caddr = sock.accept() #< - this is a blocking call
print "Connection from: " + `caddr`
req = csock.recv(1024) # get the request, 1kB max
will at least recieve a message from the client after accepting the incomming connection
what you probably need to do is hand the connection off to a seperate thread to work with so you can continue to accept new connections , while processing the current connection

socket.send working only once in python code for an echo client

I have the following code for an echo client that sends data to an echo server using socket connection:
echo_client.py
import socket
host = '192.168.2.2'
port = 50000
size = 1024
def get_command():
#..Code for this here
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
while 1:
msg = get_command()
if msg == 'turn on':
s.send('Y')
elif msg == 'turn off':
s.send('N')
elif msg == 'bye bye':
break
else:
s.send('X')
data = s.recv(size)
print 'Received: ',data
s.close()
echo_server.py
import socket
host = ''
port = 50000
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
while 1:
client, address = s.accept()
data = client.recv(size)
if data:
client.send(data)
client.close()
The problem im facing is that in the client s.send works only the first time even though its in an infinite loop. The client crashes with connection timed out, some time after the first send/receive has completed.
Why is s.send working only once ?. How can i fix this in my code ?
Please Help
Thank You
Your server code only calls recv once. You should call accept once if you only want to receive one connection, but then you need to loop calling recv and send.
Your problem is that you are blocking on the accept inside the server's loop.
This is expecting the server to accept connections from more than one client. If you want that, and for each client to send multiple commands, you would need to spawn a new thread (or process) after the accept, with a new while loop (for client communication) in that thread/process.
To fix your example to work with just one client, you need to move the accept outside the loop, like so:
client, address = s.accept()
while 1:
data = client.recv(size)
if data:
client.send(data)

Reading data send from StreamRequestHandler write

I have a SocketServer.StreamRequestHandler server that calls self.rfile.readline() to read a request and then calls self.wfile.write(data) to send back some data:
class FileServerHandler(SocketServer.StreamRequestHandler):
def handle(self):
# self.rfile is a file-like oject created by the handler
data = self.rfile.readline()
if data == "msg":
self.wfile.write(someOtherData)
I want my client to be able to send the request and receive the "someOtherData" from the server:
# Create a socket (SOCK_STREAM means a TCP socket)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
sock.send("msg")
print sock.recv(1024)
sock.close()
But the client hangs when I try this. Where am I going wrong? Also is it necessary to know how much data the socket recv's or is there a way to just receive all the data the server writes?
As your server is doing a self.rfile.readline() it is constantly reading until it receives a newline ("\n") character. Thus your client needs to send sock.send("msg\n") for it to terminate the read command.
beside Jan answers I like to mention if you want to receive your exact message, you need to use strip to drop '\n' that you have put at the end of your string .

Categories

Resources