How can I close the connection before have received the response - python

In a simple code like this
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.send(request)
I have the need of not having the response from the host to arrive. Is that possible? If yes, how can I do that?
I already tried writing
s.close()
but the responses arrive
P.S. the host I connect to is a proxy, if it's useful to say.
so even if the response phisically comes from proxy, in reality it is natively generated by the site (not the proxy, the proxy is the intermediate). so i need to not listen the answer, the response of proxy. Just need to send the request

Related

Can I make a client socket only to establish a connection using python 3.6

I'm reading about socket module in a web learning site about python, they gave us a simple steps to use socket module like follows:
import socket
with socket.socket() as client_socket:
hostname = '127.0.0.1'
port = 9090
address = (hostname, port)
client_socket.connect(address)
data = 'Wake up, Neo'
data = data.encode()
client_socket.send(data)
response = client_socket.recv(1024)
response = response.decode()
print(response)
when executing I got the error message:
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it.
when I searched about this some sites was talking about server listening and I see in most of tutorials about server socket and they use it along with client one.
so Is the error message related to the fact that I'm not using a server socket and is it a must to use them both
Update:
after reading the answers I got, I went to the test.py file that the course instructors use to evaluate our codes and I see that they make the server socket in it , so the server is already made by them. that take me back to the Error I got why does it happen then.
def server(self):
'''function - creating a server and answering clients'''
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind(('localhost', 9090))
self.ready = True
try:
self.sock.listen(1)
conn, addr = self.sock.accept()
self.connected = True
conn.settimeout(15)
while True:
data = conn.recv(1024)
self.message.append(data.decode('utf8'))
if len(self.message) > 1_000_000:
conn.send(
json.dumps({
'result': 'Too many attempts to connect!'
}).encode('utf8'))
break
if not data:
break
Each connection requires a client, which initiates the connection, and a server, which listens for the incoming connection from the client. The code you have shown is for the client end of the connection. In order for this to run successfully you will need a server listening for the connection you are trying to create.
In the code you showed us you have the lines
hostname = '127.0.0.1'
port = 9090
address = (hostname, port)
client_socket.connect(address)
These are the lines that define what server you are connecting to. In this case it is a server at 127.0.0.1 (which is localhost, the same machine you are running the code on) listening on port 9090.
If you want to make your own server then you can look at the documentation for Python sockets and the particular functions you want to know about are bind, listen, and accept. You can find examples at the bottom of that same page.
Given that you appear to have found this code as part of a course, I suspect they may provide you with matching server code at some point in order to be able to use this example.

Received data from python SSL server is incorrect

I am trying to modify a socket server I wrote with the python socket library to use encryption using python's SSL library.
I am no able to successfully open a connection to the server, wrap it with an SSL context and send data to the server, but data sent back to the client is not what it should be.
My suspicion is that the server responses are not being decrypted on the client side, but I don't know why. I'm pretty new to SSL/TLS, and networking in general so... what am I missing?
The client is also written in python (for now, to facilitate testing)
Code:
Relevant Server stuff:
def sslServerLoop():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(5)
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain('cert.pem')
while True:
conn, addr = s.accept()
sslConn = context.wrap_socket(conn, server_side=True)
data = sslConn.recv(1024)
sslConn.sendall(response)
sslConn.close()
Relevant Client stuff:
context = ssl.create_default_context(cafile='cert.pem')
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s = context.wrap_socket(s, server_hostname=server_addr)
s.connect((address, port))
s.sendall(msg)
s.shutdown(socket.SHUT_WR)
response = s.recv(1024)
Sending from client to server works fine, but data sent back to the client is wrong. For example if I set response = bytes([1]) on the server side, I receive b'\x17\x03\x03\x00\x19\xac\xb6\x7f#\xc0\xd3\xce%\x13G\x01\xbd\x88y\xf0\xda..\x02\xf9\xe4o\xdd\x1a\xdb' on the client side. Most of that changes every time I try to run it, but the first 5 bytes are always the same (which is partly why I suspect it isn't being decrypted).
cert.pem is a self signed certificate generated using openssl as described in the python 3 SSL module documentation
It is not legal to shutdown a socket that is being used for SSL. It is a protocol violation. You must close via the SSL/TLS API you are using.

Why include host in python socket request as well?

I see examples where people create the socket object from a host and port but then also send a GET request, and include the Host header inside the http request.
import socket
HOST = 'daring.cwi.nl'
PORT = 80
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall("GET / HTTP/1.1\r\n\r\nHost: daring.cwi.nl")
data = s.recv(1024)
print('Received', repr(data))
Why do we need to provide the host once to create socket object and again to send the request?
First, if you are using just a normal tcp connection, you can send anything you want, you can s.sendall("HAHAHA").
Second, In your code, it is simulating a Get http request. To send parameters, you just need to concatenate them after url. /?parameter1=value1&parameter2=value2.
Finally, why we need to include Host again? Assume you are sending this request to a load-balance server, the application server cannot get real Host without you explicitly sending it.
The Host header is required by the HTTP standard (at least version 1.1), i.e. the standard which defines the protocol spoken with a web server. The reason for this is that you can have multiple domains share the same IP address and thus the web server somehow needs to find out which of the domains you want to access. Since the lower layer (i.e. TCP) does not contain this information but only the IP address you need to provide this information at the application layer (i.e. HTTP).
As for using the hostname inside the connect: This is actually not needed and you could also provide the IP address there. All what it does when providing the hostname and not the IP is to lookup the IP address for the host and connect to this.

TCP Server and Client

So i'm trying to write a TCP server and client so that when the client connects, a file is sent back from the server. Here's my code for the server:
import socket
import threading
bind_ip = '0.0.0.0'
bind_port = 9999
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_ip, bind_port))
server.listen(10)
file_to_send = ('file_to_send.txt')
print '[*] Listening on %s:%d' % (bind_ip,bind_port)
def handle_client(client_socket):
request = client_socket.recv(1024)
print '[*] Received %s' % request
client_socket.send('')
client_socket.close(file_to_send)
while True:
client,addr = server.accept()
print '[*] Accepted connection from: %s:%d' % (addr[0],addr[1])
client_handler = threading.Thread(target=handle_client,args=(client,))
client_handler.start()
And here is my code for the client:
import socket
target_host = '0.0.0.0'
target_port = 9999
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host,target_port))
client.send('ACK!')
response = client.recv(4096)
print response
When the server and client are run, the server returns the error 'Only one usage of each socket address (protocol/network address/port) is normally permitted' and when the client is run I get the error ' The requested address is not valid in its context'
Does anyone know why these errors are occurring or how I might be able to fix it.
I think this is a case of inaccurate example code. The server code you posted does not cause the issue you're describing (the client code does, but we'll get to that).
Server
The issue with the server code is that you're binding to the same (address, port) twice. Whether this is from wrong indentation or wrong logic it's tough to say, but that error message comes from binding the same protocol to the same address with the same port number more than once at the same time.
The rest of the code seems fine, though you can't do client_socket.close("some string") as you're doing here. socket.close does not accept any arguments.
Client
There's a simple solution here -- just change the target_host to something reasonable. You cannot connect to 0.0.0.0. This should be the addressable IP of the server in the smallest scope possible. Presumably if this is a toy program this is something like localhost.
(N.B. you bind the server to '0.0.0.0' to tell it to accept connections going to any destination IP. You could bind the server instead to '127.0.0.1' to inform the server that it will ONLY be known as localhost and never anything else.)
I've had a similar issue before and it was that I was running old versions of the program on the same port, restarting the PC or closing the processes in task manager should fix it.
I'm aware that this was asked over a year ago, so OP has probably restarted their PC since then, but hopefully this will help someone looking for a solution for a similar problem.

Client Python close my TCP connection without socket.close()

I am developing a TCP client on Python, and I have the next problem. I connect with the server, I send it some data, it response me with the data expected but after this the my own application (client) send a [FIN, ACK] (checked with wireshark). Here is my client app:
try:
sock = socket(AF_INET, SOCK_STREAM)
sock.bind((my_ip,my_port))
sock.connect((sendAddress,sendPort))
sock.send(joinRequest)
joinResponse = sock.recv(18)
print joinResponse
except socket.timeout:
sock.close()
This is the default behavior of SocketServer, accept a connection, get the request, and then close the connection.
The simple way will be to use while loop to keep it connected, You can also use sock.settimeout to tune the timeout

Categories

Resources