I am currently learning about networking with Python and have created a simple TCP server and client. The client and server connect just fine, however, when I run the client script and input something from the prompt I get a NameError exception for the input I entered. This shouldn't be the case as the input is supposed to be referenced by an identifier (data).
I've gone through the code but can't seem to find the issue. Please see both the client and server code below:
Client script:
#!/usr/bin/env python
from socket import *
from time import ctime
HOST = 'localhost'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)
while True:
data = input('> ')
if not data:break
tcpCliSock.send(data)
data = tcpCliSock.recv(BUFSIZ)
if not data:break
print(data.decode('utf-8'))
tcpCliSock.close()
Server script:
from socket import *
from time import ctime
HOST = ""
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
while True:
print("waiting for a connection.....")
tcpCliSock, addr= tcpSerSock.accept()
print("....connected from:", addr)
while True:
data = tcpCliSock.recv(BUFSIZ)
if not data:break
tcpCliSock.send(bytes('[%s] %s' % (ctime(), 'utf-8'), data))
tcpCliSock.close()
tcpSerSock.close()
Many thanks!
The input builtin you used in your client script evaluates the user's input as Python code (which is what generates the NameError). Use raw_input instead to simply get text input from the user.
Related
I'm creating a program that uses threads to handle sockets and input at the same time. I've narrowed down the errors I'm getting to be replicable in these couple dozen lines of code. What happens to anyone else who runs the code below? I encounter a hang-up in waiting for the recv in the client. If I further try to send() more data in the server, I get a Broken Pipe error. And, even more weirdly, if I comment out the line that calls input(), the sockets work just fine.
What kind of weird interaction is going on between input(), sockets, and threading? And does anyone have a solution to this? Here's some code that generates the error.
Server:
import socket
import threading
def handle_connection(conn, addr):
data = conn.recv(1024)
message = data.decode('ascii').split()
s = "TEST"
conn.send(bytes(s, 'ascii')) #
conn.close()
def handle_input():
while True:
s = input()
print(s)
HOST = "127.0.0.1" # The server's hostname or IP address
PORT = 2000 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT)); #Empty first string = INADDR_ANY
s.listen();
w = threading.Thread(target=handle_input)
w.start()
while True:
conn, addr = s.accept()
x = threading.Thread(target=handle_connection, args=(conn, addr))
x.start()
s.close()
Client:
import socket
HOST = "127.0.0.1" # The server's hostname or IP address
PORT = 2000 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
message = "find_successor a"
s.connect((HOST, PORT))
s.sendall(bytes(message, 'ascii'))
data = s.recv(1024)
print(f"Received {data!r}")
I appreciate any help or insight!
I am building a simple network chat in Python using UDP, however, when I run the server code on one machine and the client on another, no message is received by the server and no message is sent back to the client by the server script. Here is my code:
Server:
import socket, sys
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', 9997)) #need higher port
while True:
x = raw_input("Enter your message: ")
sent = sock.sendto(x, ('', 9997))
data, address = sock.recvfrom(4096)
print data, " ", address
sock.close()
Client:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
print "Waiting to receive"
data, server = sock.recvfrom(4096)
print data
x = raw_input("Enter message: ")
sent = sock.sendto(x, server)
sock.close()
Does anyone know what I am doing wrong here? Is is possible that code is fine, but the UDP is not reliable enough and is dropping the message?
As I said, since your code seems a little unclear (to me, at least), I'm posting you a very similar working example.
Here's the Server:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('localhost', 1932)
sock.bind(server_address)
BUFFER_SIZE = 4096
try:
while True:
data, address = sock.recvfrom(BUFFER_SIZE)
print "Client sends: ", data
reply = raw_input("Your response:\n")
sock.sendto(reply,address)
except KeyboardInterrupt:
sock.close()
The server creates a socket and binds it to its address and the port it's listening to, 1932 in our case. He waits for an incoming message, asks for a reply, then sends it back to the sender.
Here's the Client:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client_address = ('localhost', 1931)
server_address = ('localhost', 1932)
sock.bind(client_address)
BUFFER_SIZE = 4096
try:
first_msg = raw_input("Your first message:\n")
sock.sendto(first_msg,server_address)
while True:
data, address = sock.recvfrom(BUFFER_SIZE)
print "Client sends: ", data
reply = raw_input("Your response:\n")
sock.sendto(reply,address)
except KeyboardInterrupt:
sock.close()
It's very similar to the server, the only difference is that it sends a message before the while loop, in order to start the conversation. Then it just enters the receive/reply loop, just as the server does. It has the server address too, that is different (different port, since I'm on localhost)
The try/catch block is here just to close gracefully the whole process.
I used localhost and different ports on my computer and tested it, and it works. You should just change the addresses to get it working over LAN, and you could keep the same port if the addresses are different, it should work.
So, I have a server sending responses to a client with the socket.send() method. From time to time testing the code on localhost, the socket.recv() method, used by the client to receive the server responses, gets two different messages in one, when the server uses socket.send() twice in a row.
For example:
Server:
from socket import *
serverSocket = socket(AF_INET, SOCK_STREAM)
serverPort = 13005
serverSocket.bind(('', serverPort))
serverSocket.listen(1)
connection_socket, client_ip = serverSocket.accept()
connection_socket.send('Message one')
connection_socket.send('Message two')
Client:
from socket import *
serverName = 'localhost'
serverPort = 13005
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((serverName, serverPort))
print clientSocket.recv(1024)
print clientSocket.recv(1024)
The result from running the client, at random times, is
Message oneMessage two
unless I put a sleep(0.1) between the two send(). Is there a way to avoid using sleep? Do I need to put the exact number of bytes to receive in the recv() method?
TCP is a stream oriented protocol and don't send message one by one. A easy way to split the messages that you can set a split string in the end of message like \r\n
Example:
Client:
#!/usr/bin/env python
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 13005
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send('Message one\r\n')
s.send('Message two\r\n')
s.close()
Server:
#!/usr/bin/env python
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 13005
BUFFER_SIZE = 20 # Normally 1024, but we want test
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn, addr = s.accept()
data = ''
while 1:
data += conn.recv(BUFFER_SIZE)
if not data: break
if not data.endswith('\r\n'):
continue
lines = data.split('\r\n')
for line in lines:
print line
data = ''
conn.close()
If your message is complicated and long, you can see: Python Socket Receive Large Amount of Data
I am having some problems adding in a logging file for my python TCP server code.
I've looked at some examples, but as I don't have much experience in writing my own scripts/codes, I'm not very sure how to go about doing this. I would appreciate if someone could guide me in the right direction with explanation and some examples if possible.
I am using HERCULES SETUP UTILITY , which acts as my TCP client, while my visual studio python code acts as a SERVER. My SERVER can receive the data which is sent by the client by now , I just can't seem to add in a logging file which can save the sent data into text file.Can someone please show me some examples or referance please? Your help would mean alot. This is my code so far :
from socket import *
import thread
BUFF = 1024 # buffer size
HOST = '172.16.166.206'# IP address of host
PORT = 1234 # Port number for client & server to recieve data
def response(key):
return 'Sent by client'
def handler(clientsock,addr):
while 1:
data = clientsock.recv(BUFF) # receive data(buffer).
print 'data:' + repr(data) #Server to recieve data sent by client.
if not data: break #If connection is closed by client, server will break and stop recieving data.
print 'sent:' + repr(response('')) # respond by saying "Sent By Client".
if __name__=='__main__':
ADDR = (HOST, PORT) #Define Addr
serversock = socket(AF_INET, SOCK_STREAM)
serversock.bind(ADDR) #Binds the ServerSocket to a specific address (IP address and port number)
serversock.listen(0)
while 1:
print 'waiting for connection...'
clientsock, addr = serversock.accept()
print '...connected from:', addr #show its connected to which addr
thread.start_new_thread(handler, (clientsock, addr ))
In context, maybe something like this?
#!/usr/local/cpython-2.7/bin/python
import socket
import thread
BUFF = 1024 # buffer size
HOST = '127.0.0.1'
PORT = 1234 # Port number for client & server to recieve data
def response(key):
return 'Sent by client'
def logger(string, file_=open('logfile.txt', 'a'), lock=thread.allocate_lock()):
with lock:
file_.write(string)
file_.flush() # optional, makes data show up in the logfile more quickly, but is slower
def handler(clientsock, addr):
while 1:
data = clientsock.recv(BUFF) # receive data(buffer).
logger('data:' + repr(data) + '\n') #Server to recieve data sent by client.
if not data:
break #If connection is closed by client, server will break and stop recieving data.
logger('sent:' + repr(response('')) + '\n') # respond by saying "Sent By Client".
if __name__=='__main__':
ADDR = (HOST, PORT) #Define Addr
serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversock.bind(ADDR) #Binds the ServerSocket to a specific address (IP address and port number)
serversock.listen(0)
while 1:
logger('waiting for connection...\n')
clientsock, addr = serversock.accept()
logger('...connected from: ' + str(addr) + '\n') #show its connected to which addr
thread.start_new_thread(handler, (clientsock, addr))
HTH
It sounds to me like your question would be better rephrased as “How do I read and write files within Python?”.
This is something well documented at: http://docs.python.org/2.7/tutorial/inputoutput.html#reading-and-writing-files
Example:
f = open('/tmp/log.txt', 'a')
f.write('Doing something')
do_something()
f.write('Other stuff')
other_stuff()
f.write('All finished')
f.close()
I am implementing a program with a server and multiple clients. All clients send data to the server and a server check out the step of each client. If all client's steps are the same, a server sends new data to all clients to do next step. And it continues this procedure again and again.
However, when I run my program, it cannot communicate each other. Here are my code. Would you give me some hints?
client & server
#client
from socket import *
from sys import *
import time
import stat, os
import glob
# set the socket parameters
host = "localhost"
port = 21567
buf = 1024
data = ''
addr = (host, port)
UDPSock = socket(AF_INET, SOCK_DGRAM)
UDPSock.settimeout(100)
def_msg = "=== TEST ==="
#FILE = open("test.jpg", "w+")
FILE = open("data.txt","w+")
while (1):
#data, addr = UDPSock.recvfrom(buf)
print "Sending"
UDPSock.sendto(def_msg, addr)
#time.sleep(3)
data, addr = UDPSock.recvfrom(buf)
if data == 'done':
FILE.close()
break
FILE.write(data)
print "Receiving"
#time.sleep(3)
UDPSock.close()
# server program for nvt
from socket import *
import os, sys, time, glob
#import pygame
import stat
host = 'localhost'
port = 21567
buf = 1024
addr = (host, port)
print 'test server'
UDPSock = socket(AF_INET, SOCK_DGRAM)
UDPSock.bind(addr)
msg = "send txt file to all clients"
#FILE = open("cam.jpg", "r+")
FILE = open("dna.dat","r+")
sending_data = FILE.read()
FILE.close()
tmp_data = sending_data
while (1):
#UDPSock.listen(1)
#UDPSock.sendto(msg, addr)
#FILE = open("gen1000.dat","r+")
#sending_data = FILE.read()
#FILE.close()
#print 'client is at', addr
data, addr = UDPSock.recvfrom(buf)
#time.sleep(3)
print data
#msg = 'hello'
#
tmp, sending_data = sending_data[:buf-6], sending_data[buf-6:]
if len(tmp) < 1:
msg = 'done'
UDPSock.sendto(msg, addr)
print "finished"
sending_data = tmp_data
UDPSock.sendto(tmp, addr)
print "sending"
#time.sleep(3)
UDPSock.close()
A server must perform the sequence socket(), bind(), listen(), accept() (possibly repeating the accept() to service more than one client), while a client only needs the sequence socket(), connect().
Your missing listen() i saw first. Listen for connections made to the socket.
More on this here: link text
Look at this: http://heather.cs.ucdavis.edu/~matloff/Python/PyNet.pdf
It's a very good Python networking tutorial including working examples of a client and server. Now, I'm not an expert on this, but it looks to me like your code is overcomplicated. And what's the deal with all the commented-out lines?
Quote from question:
#UDPSock.listen(1)
#UDPSock.sendto(msg, addr)
#FILE = open("gen1000.dat","r+")
#sending_data = FILE.read()
#FILE.close()
End quote
Those look like some pretty important lines to me.
Also, make sure the computers are connected. From a prompt run:
ping [IP]
where [IP] is the IP address of the other machine(Note: if you're not connected to the same LAN, this becomes much harder as you might then need port forwarding and possibly static IPs).