I have recently starting learning network programming with python. Here is a simple server I tried to write:
import socket
def server():
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('127.0.0.1', 1024))
while True:
data, address = sock.recvfrom(65535)
text = data.decode('ascii')
print('the client from {0} sent: "{1}"'.format(address, text))
if text is '0': break
I wanted the server to wait till it is getting packets from the server, but when I run it, it will close instantly.
what did I do wrong?
You're not actually calling server().
Add this after the function definition:
if __name__ == '__main__':
server()
Related
Hi I am trying to create a very simple peer-to-peer chatting program in python. The first user can runs the server.py program below to bind to a socket.
import sys
import socket
import select
import threading
# Bind to socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('127.0.0.1', 11111))
s.listen()
def chat(conn, addr):
# Set blocking to false so that program can send and receive messages at the same time
conn.setblocking(0)
# Receive messages using select
while conn in select.select([conn], [], [], 0)[0]:
text = conn.recv(4096)
if text:
print("{}: {}".format(addr, text))
else:
return
# get user input and send message
while True:
msg = input(">>>")
conn.send(msg.encode())
if __name__ == '__main__':
## Accept connections and start new thread
(conn, addr) = s.accept()
threading.Thread(target=chat, args=([conn, addr])).start()
Then another user can use netcat to connect to the server and communicate. However, the program is only able to get the user's input and send to the other side. The user from the other side is unable to send messages.
input() blocks, so you are falling through your chat function and entering the input() loop and never checking for receiving again. Receive on the thread and enter the input loop on the main thread. TCP is full duplex so you can send/recv at the same time on two threads without turning off blocking.
I also needed to add a newline to the send() as my netcat was line-buffering.
import socket
import threading
# Bind to socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 11111))
s.listen()
def chat(conn, addr):
while True:
text = conn.recv(4096)
if not text: break
print("{}: {}".format(addr, text))
if __name__ == '__main__':
## Accept connections and start new thread
conn, addr = s.accept()
threading.Thread(target=chat, args=(conn, addr), daemon=True).start()
# get user input and send message
while True:
msg = input(">>>")
conn.sendall(msg.encode() + b'\n')
So I am new to python and I'm trying to learn some socket programming and the following script, when ran and connected to the server via telnet, returns me something like "hheelllloo wwoorrlldd" instead of letting me write "hello world" and then send the data. I've looked online and I've already tried to change the localecho setting in telnet and that didn't work either.
The servers script is:
import socket
import sys
import threading
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 10000))
sock.listen(1)
connections = []
def handler(c, a):
global connections
while True:
data = c.recv(1024)
for connection in connections:
connection.send(bytes(data))
if not data:
connections.remove(c)
c.close()
break
while True:
c, a = sock.accept()
conn_thread = threading.Thread(target = handler, args = (c, a))
conn_thread.daemon = True
conn_thread.start()
connections.append(c)
The code when ran should return the sender the text he sent. I think mine does it character by character, without pressing enter to send and I don't know why. I might be wrong though.
Also, I'm running Windows 10, if this matters.
I am trying to make a server-client program using threads to handle each client, but the server will only accept one client at a time. If the first client disconnects, then the second client is accepted. Furthermore, each client can only send data once, then the program fails to send any more.
Prior to posting, I have looked at MANY other Stack Overflow posts, including the following:
how can I make a server communicate with more than 1 client at the same time?
python multithreaded server
My Python socket server can only receive one message from the client
But through looking at these posts I have found no solution.
Here is the server code:
import socket
from threading import *
def main():
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('172.20.3.62', 5000))
s.listen(1)
clients = []
print("listening")
def clienthandler(c):
clients.append(c)
try:
while True:
data = c.recv(1024).decode("UTF-8")
if not data:
break
else:
print(data)
for client in clients:
client.send(data.encode("UTF-8"))
except:
clients.remove(c)
c.close()
while True:
c, addr = s.accept()
print("accepted a client")
Thread(target=clienthandler(c)).start()
if __name__ == '__main__':
main()
Here is the client code:
import socket
from threading import *
def main():
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('172.20.3.62', 5000))
print("connected")
def send():
msg = input("ENTER:")
s.send(msg.encode("UTF-8"))
def receive():
while True:
data = s.recv(1024).decode("UTF-8")
if data:
print(data)
else:
break
Thread(target=send).start()
Thread(target=receive).start()
if __name__ == '__main__':
main()
Thanks to user Rawing. His/Her solution was: Thread(target=clienthandler(c)) -> Thread(target=clienthandler, args=(c,))
This allowed for more than one thread, and I was able to solve the only one message problem by putting the client send block in a while loop.
I am trying a little client server project to get me into network programming but I seem to have got stuck at the first hurdle. I cant seem to get past getting the first line of data only even if its a new connection.
#!/usr/bin/python
import socket
s = socket.socket()
host = '192.168.0.233' # Test Server
port = 7777
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
print 'Got connection from', addr
data = c.recv(2048)
print(data)
If I telnet to the host running the server, the connection opens fine and I see on the server Got connection from addr, but I also only see the first line of data when I sent 4 lines of data,
I thought because its in a loop it should now always be looking for data?
I know im doing something wrong but unsure what.
Im using Python 2.6.6
recv needs to be in a loop too, at the moment your code is receiving some data and then waiting for a new connection.
https://docs.python.org/2/library/socket.html#example has an example of socket.recv in a loop.
Try this:
#!/usr/bin/python
import socket
import threading
def listenForClients(sock):
while True:
client, address = sock.accept()
client.settimeout(5)
threading.Thread( target = listenToClient, args = (client,address) ).start()
def listenToClient(client, address):
size = 2048
while True:
try:
data = client.recv(size)
if data:
response = "Got connection"
client.send(response)
else:
raise error('Client disconnected')
except:
client.close()
return False
def main(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((host, port))
sock.listen(5)
listenForClients(sock)
if __name__ == "__main__":
main('192.168.0.233',7777)
Here I use a thread for each client. The problem that you have with having Socket.accept() in the loop is that it blocks meaning that concurrent access won't work and you'll only be able to talk to one client at a time.
Try running it in the background and sending it messages with:
#!/usr/bin/python
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('192.168.0.233',7777))
vwhile True:
data = raw_input("enter a message: ")
sock.send(data)
print sock.recv(2048)
I'm trying to use xinetd to remotely run a command (traccejob). When I connect through telnet, everything works fine. Unfortuantely, the client that I've written doesn't seem to receive the data from the server. The code looks like:
server:
import sys
import commands
def main():
tjinput = sys.stdin.readline().strip()
(ret, out) = commands.getstatusoutput('/usr/bin/tracejob '+tjinput)
print out
sys.stdout.flush()
if __name__ == "__main__":
main()
client:
host = 'xxx.xxx.xxx.xxx'
port = 12345
import socket
import sys
def main(argv):
message = 'hello'
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((host, port))
sock.send(message)
data = sock.recv(1024)
sock.close()
print repr(data)
if __name__ == '__main__':
main(sys.argv)
The client process stops on the sock.recv(1024) line. I can't for the life of me tell why sock.recv isn't reading the output from the socket. Probably a coding issue? If it helps, the xinetd.d file looks like this:
service tracejob
{
flags = IPv4
disable = no
socket_type = stream
wait = no
user = root
group = root
server = /usr/local/bin/tracejob_xinetd.py
port = 12345
type = UNLISTED
}
where tracejob_xinetd.py is the server described above.
Any tips? Thanks in advance.
You have a deadlock situation: The client sends an incomplete line and waits for the server to send something, the server waits for line completion or EOF before it sends a reply.
So you have now 2 ways to proceed now:
Append a \n to the string being sent.
"Half-close" the socket on client side with sock.shutdown(socket.SHUT_WR) after writing, but before reading.