So I'm unable to actually print all of the information that I see after issuing a "help" command. Do i need to change the length of the skt.receive()? Or is there a way to simply print all of the data that comes through? It seems like there has to be a way to account for a data that you want to print of an unknown length? Or am I approaching this in the wrong way.
Thanks.
#!/usr/bin/python
host = '192.168.1.50'
port = 23
msg = "help\r"
msg2 = "y\r"
import socket
import sys
import time
try:
skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, e:
print("Error creating socket: %s" % e)
sys.exit(1)
try:
skt.connect((host,port))
except socket.gaierror, e:
print("Address-related error connecting to server: %s" % e)
sys.exit(1)
except socket.error, e:
print("Error connecting to socket: %s" % e)
time.sleep(15)
skt.connect((host,port))
sys.exit(1)
try:
print(skt.send(msg))
skt.send('help\r')
print("SEND: %s" % msg)
except socket.error, e:
print("Error sending data: %s" % e)
sys.exit(1)
while 1:
try:
buf = skt.recv(50000000000)
if(len(buf)):
print(buf)
if 'AMX' in buf:
print("Length buff")
if 'AMX' in buf:
print(skt.send(msg))
#print("first wait")
#print("RECV: %s" % buf)
#time.sleep(9)
#print("second wait")
sys.exit(1)
except socket.error, e:
print("Error receiving data: %s" % e)
sys.exit(1)
if not len(buf):
break
sys.stdout.write(buf)
Have you considered using telnetlib, rather than re-inventing the wheel? :)
Example:
import telnetlib
HOST = "192.168.1.50"
tn = telnetlib.Telnet(HOST)
tn.write("help\n")
print tn.read_all()
So the telnetlib def makes things easier and streamlines the process. No sense in reinventing the wheel.
Related
When I run the server, then the client, I Automatically get these messages:
**SERVER: **
Traceback (most recent call last):
File "C:\Users\Ryan\Desktop\testproj-server.py", line 142, in
handleConnectedSocket()
File "C:\Users\Ryan\Desktop\testproj-server.py", line 58, in handleConnectedSocket
rcvdStr = rcvdStr + fd.recv(1024)
TypeError: can only concatenate str (not "bytes") to str
**CLIENT: **
ERROR: Cannot connect to chat server [WinError 10056] A connect request was made on an already connected socket
Exiting... Goodbye! *
This is my code:
SERVER CODE:
import socket
import select
def runSelect():
selectUnsuccessful = True
while selectUnsuccessful:
try:
readyRecvList, readySendList, readyErrList = select.select(recvList, sendList, [])
selectUnsuccessful = False
except select.error:
for fd in recvList:
try:
tempRecvList, tempSendList, tempErrList = select.select([fd], [], [], 0)
except select.error:
if fd == serverSocket:
fd.close()
exit(1)
else:
if fd in recvList:
recvList.remove(fd)
fd.close()
return readyRecvList, readySendList
def handleListeningSocket():
try:
newConnectionSocket, addr = serverSocket.accept()
except socket.error as err:
print("\nERROR: Something went wrong in the accept() function call:", err)
exit(1)
try:
recvList.append(newConnectionSocket)
sendList.append(newConnectionSocket)
print("INFO: Connecting socket created between %s and %s" %
(newConnectionSocket.getsockname(), newConnectionSocket.getpeername()))
print("* Client %s is ready to chat *" % (str(newConnectionSocket.getpeername())))
except (socket.error, socket.gaierror) as err:
print("\nERROR: Something went wrong with the new connection socket:", err)
if newConnectionSocket in recvList:
recvList.remove(newConnectionSocket)
sendList.remove(newConnectionSocket)
newConnectionSocket.close()
def handleConnectedSocket():
try:
recvIsComplete = False
rcvdStr = ""
while not recvIsComplete:
rcvdStr = rcvdStr + fd.recv(1024)
if fd not in sendList:
sendList.append(fd)
# ~ is the delimiter used to indicate message start and finish
if rcvdStr.strip('~') != "":
if (rcvdStr[0] == "~") and (rcvdStr[-1] == "~"):
recvIsComplete = True
clientMessage = rcvdStr.strip('~')
else: # if empty string, connection has been terminated
if fd in recvList:
recvList.remove(fd)
if fd in sendList:
sendList.remove(fd)
del clientMessages[fd] # Delete connection information
fd.close()
if clientMessage == "quit()":
print ("\n* Client %s has left the chat room *\n" % (str(fd.getpeername())))
if fd in recvList:
recvList.remove(fd)
fd.close()
if fd in sendList:
sendList.remove(fd)
fd.close()
else:
print("\n%s: %s" % (fd.getpeername(), clientMessage))
# add message to dictionary, pending transmission
clientMessages[fd] = str(clientMessage)
except socket.error as err:
print("\nERROR: Connection to the client has abruptly ended:", err)
if fd in recvList:
recvList.remove(fd)
if fd in sendList:
sendList.remove(fd)
fd.close()
print("* I am ready to chat with a new client! *\n")
"""
main - Runs the Full Duplex Chat server
"""
# Global Variables
serverHost = 'localhost'
serverPort = 22222
recvList = []
sendList = []
clientMessages = {}
try:
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.setblocking(0)
serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serverSocket.bind((serverHost, serverPort))
serverSocket.listen(3)
print ("INFO: I am listening at %s" % (str(serverSocket.getsockname())))
print ("* I am ready to chat with a new client! *\n")
except (socket.error, socket.gaierror) as err:
print ("\nERROR: Something went wrong in creating the listening socket:", err)
exit(1)
recvList = [serverSocket]
try:
while True:
serverSocket.setblocking(False)
readyForRecv, readyForSend = runSelect()
for fd in readyForRecv:
if fd == serverSocket:
handleListeningSocket()
else:
handleConnectedSocket()
for fd in readyForSend:
try:
if fd in clientMessages.keys(): # See if connection information exists
broadcast = str(clientMessages[fd]) # Add message to broadcast variable
if broadcast: # See if a message is actually there
for client in readyForSend: # Broadcast message to every connected client
if broadcast != "":
print ("* Broadcasting message \"%s\" to %s *" % (str(broadcast), client.getpeername()))
client.send(str(fd.getpeername()) + ": " + str(broadcast))
clientMessages[fd] = "" # Empty pending messages
#except:
# print "\nERROR: Something awful happened while broadcasting messages"
#break
except socket.error as err:
print ("\nERROR: Something awful happened with a connected socket:", err)
if fd in recvList:
recvList.remove(fd)
if fd in sendList:
sendList.remove(fd)
fd.close()
except KeyboardInterrupt:
for fd in recvList:
fd.close()
for fd in sendList:
fd.close()
print ("\nINFO: KeyboardInterrupt")
print ("* Closing all sockets and exiting... Goodbye! *")
exit(0)
CLIENT CODE:
import socket
import select
import sys
def main():
serverHost = 'localhost'
serverPort = 22222
try:
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error as err:
print("ERROR: Cannot create client side socket:", err)
exit(1)
while True:
try:
clientSocket.connect((serverHost, serverPort))
except socket.error as err:
print("ERROR: Cannot connect to chat server", err)
print("* Exiting... Goodbye! *")
exit(1)
except:
print("ERROR: Something awful happened!")
exit(1)
break
recvList = [clientSocket, sys.stdin]
print("* You are now connected to chat server %s as %s *" %
(clientSocket.getpeername(), clientSocket.getsockname()))
try:
while True:
readyRecvList, readySendList, readyErrList = select.select(recvList, [], [])
for fd in readyRecvList:
if fd == sys.stdin:
message = sys.stdin.readline().rstrip()
clientSocket.sendall("~" + str(message) + "~")
if (message == "quit()"):
print("* Exiting chat room! *")
clientSocket.close()
exit(0)
break
elif fd == clientSocket:
clientSocket.settimeout(3)
try:
message = clientSocket.recv(2048)
except socket.timeout as err:
print("ERROR: The recv() function timed out after 3 seconds! Try again.")
except:
print("ERROR: Something awful happened!")
else:
if message == "":
break
else:
print("%s\n" % (message))
clientSocket.settimeout(None)
break
except select.error as err:
for fd in recvList:
try:
tempRecvList, tempSendList, tempErrList = select.select([fd], [], [], 0)
except select.error:
if fd == clientSocket:
fd.close()
exit(1)
else:
if fd in recvList:
recvList.remove(fd)
fd.close()
except socket.error as err:
print("ERROR: Cannot connect to chat server", err)
print("* Exiting... Goodbye! *")
exit(1)
if fd in recvList:
fd.close()
except KeyboardInterrupt:
print("\nINFO: KeyboardInterrupt")
print("* Closing all sockets and exiting chat server... Goodbye! *")
clientSocket.close()
exit(0)
if __name__ == '__main__':
main()
You didn't decode the received bytes
rcvdStr = rcvdStr + fd.recv(1024).decode()
I haven't exactly checked, so tell me if this helps
EDIT:
Ok so for starters remove the while statement in line 17 of the client, once the client is connected to the server you can't connect again (make sure you remove the break in the new line 26)
The new line 34 is causinf errors (readyRecvList, readySendList, readyErrList = select.select(recvList, [], []))
Traceback (most recent call last):
File "C:\Users\User\Desktop\Client.py", line 93, in <module>
main()
File "C:\Users\User\Desktop\Client.py", line 34, in main
readyRecvList, readySendList, readyErrList = select.select(recvList, [], [])
io.UnsupportedOperation: fileno
I have been writing a transparent proxy server in python to log where the request is going. Most pages load e.g. google.co.uk, however, pages such as google.com get stuck loading and some pages such as a local IP get the "Connection reset" error in the browser.
Any help would be greatly appreciated.
#!/usr/bin/env python
import socket, optparse, thread
def proxy(url, port, connection, address, data):
try:
get = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
get.connect((url, port))
get.send(data)
while True:
reply = get.recv(BUFFER)
if len(reply) > 0:
connection.send(reply)
info = float(len(reply))
info = float(info / 1024)
info = "%.3s" %(str(info))
info = "%s KB" %(info)
print("[*] Request Complete: %s => %s <=" %(str(address[0]), str(info)))
else:
break
get.close()
connection.close()
except Exception as e:
get.close()
connection.close()
def handle(connection, address, data):
first = data.split("\n")[0]
url = first.split(" ")[1]
protocolPosition = url.find("://")
if protocolPosition == -1:
# No protocol so default
temp = url
else:
temp = url[(protocolPosition + 3):]
if ":" in temp:
# Port other than 80 has been specified
port = temp.split(":")[-1].strip("/")
webserver = temp.split(":")[:-1]
try:
# Incase there is ':' in the URL
webserver = "".join(webserver)
except:
pass
else:
port = 80
webserver = temp.strip("/")
print("[*] '%s' => '%s'" %(address[0], webserver))
proxy(webserver, port, connection, address, data)
receive = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
receive.bind(("0.0.0.0", PORT))
except socket.error as e:
print("Failed to bind to 0.0.0.0:%d" %(PORT))
print("Error: " + str(e))
raise SystemExit
receive.listen(MAXCONNECTIONS)
print("Listening on 0.0.0.0:%d" %(PORT))
while True:
try:
connection, address = receive.accept()
data = connection.recv(BUFFER)
thread.start_new_thread(handle, (connection, address, data,))
except KeyboardInterrupt:
break
print("\nReleasing socket")
receive.close()
Edit: After some digging around and error handling I narrowed the error down to
[Errno -2] Name or service not known
After long hours of research and testing I finally ask here.
My script has to handle multiple client connections and in the same time has to get and send a stream from another socket.
Finally I've been able to make it work but only for one user. That user connects to the socket, the script connects to the other socket, then return the stream to the client.
The script works pretty well but has a some hard limitations :
- it send the stream to the client but,
- even if the socket is in non-blocking mode I think that calling a socket inside another one is the main reason why it reacts like it was in blocking mode (because one ot these is continuously sending datas ?)
By the way I think that the select() method could allow me to do what I want, but I don't clearly understand how.
Here is the server code taht works for one client, but is blocking
#!/usr/bin/env python
# coding: utf-8
from __future__ import print_function
import sys, time, base64, socket
server_ip = 'XX.XX.XX.XX'
def caster_connect(connected_client, address):
username = 'XXXXXXX'
password = 'XXXXXXXXX'
host = 'XX.XX.XX.XX'
port = 2102
pwd = base64.b64encode("{}:{}".format(username, password).encode('ascii'))
pwd = pwd.decode('ascii')
u_message = ''
stream_type = 'CMRp'
header = \
"GET /" + str(stream_type) + " HTTP/1.1\r\n" +\
"Host " + str(host) + "\r\n" +\
"Ntrip-Version: Ntrip/1.0\r\n" +\
"User-Agent: my_script.py/0.1\r\n" +\
"Accept: */*\r\n" +\
"Authorization: Basic {}\r\n\r\n".format(pwd) +\
"Connection: close\r\n"
print("Connecting to caster...\n")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,int(port)))
s.send(header.encode('ascii'))
print("Waiting answer from caster...\n")
while True:
try:
data = s.recv(2048)
connected_client.send(data)
print("Sending data from caster at %s" % time.time())
sys.stdout.flush()
# On any error, close sockets
except socket.error, e:
print("No data received from caster : %s" % e)
print("Close client connection at %s" % format(address))
s.close()
break
return
#----------------
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((server_ip, 5680))
sock.settimeout(3)
try:
while True:
try:
sock.listen(5)
client, address = sock.accept()
print ("%s connected" % format(address) )
msg = client.recv(4096)
except socket.timeout, e:
err = e.args[0]
if err == 'timed out':
print("Timed out, retry later")
continue
else:
print(socket.error)
sock.close()
except socket.error:
print(socket.error)
sock.close()
else:
if len(msg) == 0:
print("Shutdown on client end")
sock.close()
else:
print(msg)
caster_response = caster_connect(client, address)
sys.stdout.flush()
print("Close")
client.close()
sock.close()`enter code here`
except KeyboardInterrupt:
print("W: Keyboard interrupt, closing socket")
finally:
sock.close()
And this is the code I found to handle select()
#!/usr/bin/env python
# coding: utf-8
import select, socket, sys, Queue
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(0)
server.bind(('XX.XX.XX.XX', 64000))
server.listen(5)
inputs = [server]
outputs = []
message_queues = {}
while inputs:
readable, writable, exceptional = select.select(
inputs, outputs, inputs)
for s in readable:
if s is server:
connection, client_address = s.accept()
print("New connection from %s" % client_address)
connection.setblocking(0)
inputs.append(connection)
message_queues[connection] = Queue.Queue()
else:
data = s.recv(1024)
print("Data received : %s" % data)
if data:
message_queues[s].put(data)
if s not in outputs:
outputs.append(s)
else:
if s in outputs:
outputs.remove(s)
inputs.remove(s)
s.close()
del message_queues[s]
for s in writable:
try:
next_msg = message_queues[s].get_nowait()
print("Next msg : %s" % next_msg)
except Queue.Empty:
outputs.remove(s)
else:
s.send(next_msg)
for s in exceptional:
inputs.remove(s)
if s in outputs:
outputs.remove(s)
s.close()
del message_queues[s]
In this code (found at this page) I didn't make changes as I don't know how to handle this.
Maybe by creating another server script that would only handle the stream part, so the main script would act as a server for clients, but as client for the stream part ?
I have the next undesirable behaviour:
def run(self):
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._socket.bind(("0.0.0.0", self.port()))
self._socket.listen(5)
self._socket.settimeout(5.0)
while not self.finish.isSet():
try:
conn, addr = self._socket.accept()
c = connection(conn, addr)
self.activeconn.append(c)
c.start()
print "New session from address {}".format(addr)
except Exception as e:
print e
self.activeconn = self.child_list()
self._socket.close()
print "Server is closing..."
for conn in self.activeconn:
conn.join()
time.sleep(4)
print "Server is closed"
Here I have echo server with timeout set by settimeout(5.0). The problem is my console prints "timed out" every time timeout is expired. Can I turn this off somehow?
Whenever a timeout occurs during an operation on a socket, the socket.timeout exception is raised. In your code, you are catching that exception and printing it:
try:
conn, addr = self._socket.accept()
# ...
except Exception as e:
print e
If you want to prevent "timed out" lines from appearing in your output, just catch the exception and suppress it:
try:
conn, addr = self._socket.accept()
# ...
except socket.error:
pass
except Exception as e:
print e
Im coding a python script that connects to a remote server, and parses the returned response. For some odd reason, 9 out of 10 times, Once the header is read, the script continues and returns before getting the body of the response. Im no expert at python, but im certain that my code is correct on the python side of things. Here is my code:
class miniclient:
"Client support class for simple Internet protocols."
def __init__(self, host, port):
"Connect to an Internet server."
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(30)
try:
self.sock.connect((host, port))
self.file = self.sock.makefile("rb")
except socket.error, e:
#if e[0] == 111:
# print "Connection refused by server %s on port %d" % (host,port)
raise
def writeline(self, line):
"Send a line to the server."
try:
# Updated to sendall to resolve partial data transfer errors
self.sock.sendall(line + CRLF) # unbuffered write
except socket.error, e:
if e[0] == 32 : #broken pipe
self.sock.close() # mutual close
self.sock = None
raise e
except socket.timeout:
self.sock.close() # mutual close
self.sock = None
raise
def readline(self):
"Read a line from the server. Strip trailing CR and/or LF."
s = self.file.readline()
if not s:
raise EOFError
if s[-2:] == CRLF:
s = s[:-2]
elif s[-1:] in CRLF:
s = s[:-1]
return s
def read(self, maxbytes = None):
"Read data from server."
if maxbytes is None:
return self.file.read()
else:
return self.file.read(maxbytes)
def shutdown(self):
if self.sock:
self.sock.shutdown(1)
def close(self):
if self.sock:
self.sock.close()
self.sock = None
I use the ReadLine() method to read through the headers until i reach the empty line (Delimiter between headers and body). From there, my objects just call the "Read()" method to read the body. As stated before, 9 of 10 times, read returns nothing, or just partial data.
Example use:
try:
http = miniclient(host, port)
except Exception, e:
if e[0] == 111:
print "Connection refused by server %s on port %d" % (host,port)
raise
http.writeline("GET %s HTTP/1.1" % str(document))
http.writeline("Host: %s" % host)
http.writeline("Connection: close") # do not keep-alive
http.writeline("")
http.shutdown() # be nice, tell the http server we're done sending the request
# Determine Status
statusCode = 0
status = string.split(http.readline())
if status[0] != "HTTP/1.1":
print "MiniClient: Unknown status response (%s)" % str(status[0])
try:
statusCode = string.atoi(status[1])
except ValueError:
print "MiniClient: Non-numeric status code (%s)" % str(status[1])
#Extract Headers
headers = []
while 1:
line = http.readline()
if not line:
break
headers.append(line)
http.close() # all done
#Check we got a valid HTTP response
if statusCode == 200:
return http.read()
else:
return "E\nH\terr\nD\tHTTP Error %s \"%s\"\n$\tERR\t$" % (str(statusCode), str(status[2]))
You call http.close() before you call http.read(). Delay the call to http.close() until after you have read all of the data.