I'm trying to make a transparent proxy in python using the socket module. but for some reason it hangs on connect()ing the socket. here is the code i'm using:
from __future__ import division
import socket
import struct
#import mcpackets
import sys
import time
#CUSTOM SETTINGS
HOST="192.168.178.28"
PORT=25565
#END CUSTOM SETTINGS
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('',25565))
serversocket.listen(1)
print "waiting for client, press multiplayer and use 'localhost' as server"
clientsocket,address=serversocket.accept()
print "client connected from %s:%d"%address
serversocket.close()
print "connecting to '%s:%d'"%(HOST,PORT)
serversocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "socket created."
serversocket.connect((HOST,PORT))#------------------------------ freezes here
print "socket connected."
serversocket.settimeout(0)
clientsocket.settimeout(0)
print "timeouts set."
print "now proxying."
#tdata=[]
try:
while(True):
dat=None
try:
dat=clientsocket.recv(4096)
except socket.timeout:
pass
if(dat!=None):
try:
serversocket.send(dat)
except socket.timeout:
pass
#vice versa
dat=None
try:
dat=serversocket.recv(4096)
except socket.timeout:
pass
if(dat!=None):
try:
clientsocket.send(dat)
except socket.timeout:
pass
except:
clientsocket.close()
#with open("data.log","w") as fid:
# fid.write(''.join(tdata))
raise
the problem doesn't lie in the network as connecting to the server directly works fine. any ideas on what's going wrong?
This is a part of TCP sockets implementation where the operating system refuses to allow a new socket connection after a socket with the same name has been disconnected recently.
In order to force this request, set the REUSEADDR socket option on your socket, before connecting it (for both of your server socket creations):
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
This way after you close your first server socket, when you want to connect the new server socket (with the same host, port), OS would not refuse.
I'm having difficulty reproducing this as it doesn't appear to hang on Mac OS X or Windows 7 with Python 2.7. So without being able to reproduce I'm guessing there's a problem with reusing serversocket so soon after closing it on your OS. Closing a socket puts that socket into the TIME_WAIT state so it's not closed immediately. How long it takes to really close the socket is dependent on the OS and may be what's causing your problem.
Although people seem to recommend that you don't use it, you might look into using the SO_LINGER option to force the socket to close immediately.
For example:
l_onoff, l_linger = 1, 1 # send RST (hard reset the socket) after 1 second
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
struct.pack('ii', l_onoff, l_linger))
# this should now complete after l_linger timeout
serversocket.close()
Related
I have a socket that I want to timeout when connecting so that I can cancel the whole operation if it can't connect yet it also want to use the makefile for the socket which requires no timeout.
Is there an easy way to do this or is this going to be a difficult thing to do?
Does python allow a reset of the timeout after connected so that I can use makefile and still have a timeout for the socket connection
You just need to use the socket settimeout() method before attempting the connect(), please note that after connecting you must settimeout(None) to set the socket into blocking mode, such is required for the makefile .
Here is the code I am using:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
sock.connect(address)
sock.settimeout(None)
fileobj = sock.makefile('rb', 0)
If you are using Python2.6 or newer, it's convenient to use socket.create_connection
sock = socket.create_connection(address, timeout=10)
sock.settimeout(None)
fileobj = sock.makefile('rb', 0)
For setting the Socket timeout, you need to follow these steps:
import socket
socks = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socks.settimeout(10.0) # settimeout is the attr of socks.
Try this code:
try:
import socket
socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
socket.settimeout(10)
except socket.error:
print("Nope !!!")
I'm learning about sockets and connections and trying to write a simple server Python script that echos a message to a client.
I began with just running a script that prints what it receives from a socket.
So i'm running what i wrote locally and using Putty as a client (so the message isn't printed to the putty session yet).
This is my code:
import socket
HOST = '127.0.0.1'
PORT = 65432
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT)) # bind accepts a tuple of a hostname or address and a port
s.listen()
conn, addr = s.accept() # returns a pair
with conn:
print("Connection started!", conn, addr)
data = conn.recv(1024)
while data:
data = data.decode("UTF-8")
print(data)
# if data == "exit":
# shutdown and close the connection,
# and ofcourse exit the two with as blocks gracefully
data = conn.recv(1024)
print("Connection is closed and the program continued")
Running this works but i have no way of terminating the connection other then killing the server.
I believe that data will always be true since i'm using putty and it seems that even when i'm hitting enter with no text to the connection window, it actually sends this:
b'\r\n'
So I tried placing this inside the commented if statement:
conn.shutdown(socket.SHUT_RDWR)
conn.close()
Hoping this will just make the socket be deleted - but it didn't work.
So what I want to do is to exit the with blocks and deleting the sockets without having to raise any exceptions or make the program stop. I tried doing so using python 3 change to socket that made it usable with with-as statements. I tried just calling the conn.__exit__ or s.__exit__ function but that didn't work also.
How can I close the socket and exit the two with blocks using an input from the user? Is there anything i'm confusing with the socket module here?
I was trying to create a python socket server that could send and receive data, so I created a socket on the server using the code here:
import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('', 1208))
serversocket.listen(5)
(client,(ip,port)) = serversocket.accept()
Then I tried to create a sample connection from my machine by going to command prompt and typing
telnet www.filesendr.com 1208
However, the console simply replies with "Could not open connection to the host, on port 1208...Connection failed." I went back over my code but couldn't identify the problem. Any help would be greatly appreciated.
I think part of the problem is that after you accept the connection you don't do anything else. Once the accept happens, you get to the end of the script, python exits and closes all open file handles (including the socket you just opened). If you want to be able to talk to yourself through telnet, try something like this:
import socket
import select
import sys
port = 1208
listener = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
listener.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
listener.bind(('',port))
listener.listen(128)
newSock, addr = listener.accept()
while True:
r,w,e = select.select([newSock,sys.stdin],[],[])
if newSock in r:
data = newSock.recv(4096)
sys.stdout.write(data)
if sys.stdin in r:
newSock.send(sys.stdin.readline())
There are some other posts about this issue but none did help me with mine.
I'm trying to build a total simple server - client relationship in python
server.py
#!/usr/bin/python
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("127.0.0.1",8889))
s.listen(1)
try:
while True:
client, add = s.accept()
data = client.recv(1024)
if not data:
print 'No data'
print data
finally:
s.close()
client.py
#!/usr/bin/python
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1",8889))
try:
while True:
message = 'Foo'
s.send(message)
ans = s.recv(1024)
print ans
finally:
s.close()
I start by running the server first, but when I try to run the client I'm getting this Errno 10054 --> An existing connection was forcibly closed by the remote host
While request the browser with the ip and the related port, I receive some data.
I'm quiet new to networking, so please explain what might be obvious wrong in my code.
EDIT* Main issue is, that the client is somehow wrong, because it returns also an empty string on recv
Thank you in advance
Main issue is, that the client is somehow wrong, because it returns also an empty string on recv
The client isn't receiving anything from the server because the server is not sending anything.
On the server side, after print data, adding client.send(data) will send the string back to the client.
I am guessing:
The server accepts one socket and then does
client, add = s.accept()
data = client.recv(1024)
...
client, add = s.accept()
The client does this in the mean time:
s.send(message)
ans = s.recv(1024) # blocks until timeout
If now an other client connects to the server then client is replaced, the socket garbage collected and closed. s.recv(1024) will then tell that the connection is reset.
Have a look at import select or twisted (google around) to handle multiple connections at once.
I keep getting this error
[Errno 10061] No connection could be made because the target machine actively refused it.
I'm running Windows 7 64 bit, no virus or protection software, and python is allowed through my firewall (I've also tried turning my firewall completely off but same result). When I run the server and use telnet it connects just fine. When I try to connect to the server with the client it fails. Any suggestions as to what I could try to fix this? If you need more information just ask and I'll provide.
Client Code
import socket
import sys
def main():
host = ""
port = 8934
message = "Hello World!"
host = raw_input("Enter IP: ")
#Create Socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print "Failed to create socket. Error code: %s Error Message: %s"%(str(msg[0]),msg[1])
sys.exit()
print "Socket created"
#Connec to Server
print host
print port
s.connect((host,port))
print "You are connected to %s with IP adress of %s"%(host,host)
#Send Data
try:
s.sendall(message)
except socket.error:
print "Failed to send."
#Receive Data
reply = s.recv(4096)
if __name__ == "__main__":
main()
Server Code
# !usr/bin/python
import socket
import sys
HOST = ""
PORT = 8934
def main():
#Setup socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error,msg:
print "Unable to create socket"
sys.exit()
print "Socket created."
#Bind to adress
try:
s.bind((HOST,PORT))
except socket.error,msg:
print "Bind failed. Closing..."
sys.exit()
print "Socket bound."
#Start listening
s.listen(10)
print "Socket Listening"
#Accept connection
conn, addr = s.accept()
print "Connected to %s:%s"%(addr[0],addr[1])
if __name__ == "__main__":
main()
Taking a guess at your indentation, and running your codeā¦ it works just fine.* (As long as I type in 127.0.0.1 when it asks me for the IP.)
Of course the second time I run the client (if I haven't restarted the server) I get a connection-refused error. But that's just because you've coded a server that immediately quits as soon as it gets the first connection. So the second time you run the client, there is no server, so the OS rejects the connection.
You can always run the server again, which lets you run the client one more time. (Except that the server may get a 10048 error when it tries to bind the socket, because the OS is keeping it around for the previous owner. If you see that, look at SO_REUSEADDR in the docs.)
* By "works just fine" I mean that it connects, and prints out the following before quitting:
Socket created
127.0.0.1
8934
You are connected to 127.0.0.1 with IP adress of 127.0.0.1
Obviously it never sends anything to the server or receives anything back, because the server has no send or recv calls, or anything else.