Why doesn't my code respond elsewise? - python

import socket
sock = socket.socket()
sock.bind(('127.0.0.1', 1600))
sock.listen(1)
(client_sock,client_address) = sock.accept()
client_name = client_sock.recv(1024)
client_sock.send('hi its '+client_name)
client_sock.close()
sock.close();
So i run on cmd command prompt the file containing the code above, and all i get is this:
As it can be seen my cmd is as if waiting for something to happen, it doesnt print out "Hi its ..." and never ends from waiting.
Why doesn't my code work ?

It is simple: you have first to send the data and then receive. The receive command wait until the timeout (if it is set) and then go over. Remember that you have also to print the received data.
The best practice for doing what you want to do is a server-client approach having at least two different threads.

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.

TCP Socket unable to send data even after executing sendall ()

Hi I have multiple systems communicating via messages using TCP connections.
In the Process of Communication between the two, I am at first sending a message as "Start Process", for which in return it should reply as "Process Started"
However, the message "Process Started" is not received to the other system, while the line sendall ("Process Started") is executed without any exception.
My sample code is as follows:
TCP Initialisation:
def __init__(self):
self.tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.tcp.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, struct.pack('ll',0,1))
self.tcp.bind('',12000)
self.tcp.listen(1)
self.client, seld.address = self.tcp.accept()
(self.Ip,self.port)= self.address
Main Funciton:
while True:
msg =""
try:
msg = self.client.recv(512)
except socket.error as e:
if e[0] == 11:
# exception for RECVTIMEO used in the socket creation.
pass
if (msg == "Start Process"):
send = "Process Started"
self.client.sendall(send)
print "status sent"
While Executing this piece of code, I am able to receive the message "Start Process". but "Process started" is not sent though on executing the line self.client.sendall(send), I have captured the packets in wireshark, I got the packet containing "Start Process" but No packet obtained for "Process Started"
Can someone help me with this ???
Your code has several issues, but the one you are struggling with now is that if you connect to port 12000 with telnet and send "Start Process" and hit enter, you will actually send and receive Start Process\n instead of Start Process and your if statement does not match. If you strip the trailing newline, you can mitigate this:
try:
msg = self.client.recv(512)
msg = msg.strip()
Your program may need some tweaking, though. As you set your socket non-blocking, self.tcp.accept() raises an exception as you try accepting a connection that is not there yet. The same goes with self.client.recv(), after you have received the correct message. When you add strip, your if clause will match and you will get a response. However, it will just keep responding, as it immediately tries to recv(512) again, fails with an exception, then you catch it and do the if clause again. msg is still "Start Process" as it has not changed (the consecutive recv just failed, it did not return "" or None).
Try moving your if clause inside your try/except construction and only compare msg if you actually have received one.
This program would also be immensely wasteful, as it would be running in a busy loop most of the time, waiting for either connections or messages. If you need to use non-blocking sockets, you would need to address this.
A better way might be using threads to have a blocking thread that listens and accepts new connections, and for every connection it would spawn a worker thread. These threads could then be blocking in recv() until a message is received.
Just a thought.
Hannu

Python TCP socket.recv() returns with nothing as soon as connection is made

I'm trying to implement the most basic python TCP server. Windows 8, Python 2.7, firewall is turned off. Code is from here: https://wiki.python.org/moin/TcpCommunication
If I do the client stuff (socket(...), connect(...), send(...)) via python repl, things work fine, ie the server correctly blocks when calling recv.
However if I run the exact same code via python script (both with and without explicitly calling python.exe at windows command line), the recv returns immediately with no data. I read elsewhere on SO this means it's an invalid socket, but I'm not sure what that means or how to check for it. I'm using the socket returned by accept() not the one used to initiate the connection.
I'm trying to block on recv so I can take advantage of the timeout (I don't want to use select module, which BTW also returns immediately) and process some keyboard stuff between attempts to recv, ie user presses 'q' to quit.
In various experiments I've shown that once this occurs, recv will always return immediately (as will select.select(...)) if I put it in a loop, so it's not like the client is sending a single "bad" packet initially. If the client happens to have sent something, then the recv returns with that data, but it certainly doesn't block waiting for data when put in a tight loop.
Is this behavior expected?
Server code:
import sys
import socket
TCP_IP = '192.168.1.10'
TCP_PORT = 5005
BUFFER_SIZE = 20 # Normally 1024, but we want fast response
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connection address:', addr
while 1:
data = conn.recv(BUFFER_SIZE) # This returns immediately with no data, when client connection is run from script and doesn't send() anything, just connects.
if not data:
print "broken"
break
print "received data:", data
conn.send(data) # echo
conn.close()
sys.exit()
Client code:
import sys
import socket
TCP_IP = '192.168.1.10'
TCP_PORT = 5005
BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
# Commenting out the following to prove the recv() call on the other
#end returns with nothing instead of blocking indefinitely. If I
#type the rest of this at the REPL the server behaves correctly,
#ie, the recv call blocks forever until socket.send("bla") from client.
#s.send(MESSAGE) data = s.recv(BUFFER_SIZE)
#s.close()
#print "received data:", data
sys.exit()
Yes, this is expected behavior.
The client does not send anything. And it exit as soon as it connect to the server; cause disconnection.
socket.recv returns an empty string if the peer performed shutdown (disconnect).
While, in the REPL, the socket is not closed until you issue sys.exit() or you quit the interactive shell.

Python: Notification System?

I am working on a chat server that runs on my local network using socket, and then I have a client program running on all of the computers in my house, and this program allows all of the clients to talk to each other.
The problem is, you have to manually update the chat log by pressing enter.
The way I want it to work, maybe, is to check for a new message every few seconds, and if there is a new one, play a sound. Does anyone know how I can do this, I'll try to figure it out on my own, as I have done with most of this project, but any help is appreciated.
Here is the server:
import socket
import sys
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('192.168.1.80', 10000)
print >>sys.stderr, 'starting up on %s port %s' % server_address
sock.bind(server_address)
sock.listen(1)
print 'Waiting for user...'
convo='Welcome!'
while True:
# Find connections
connection, client_address = sock.accept()
try:
data = connection.recv(999)
if data=='EMPTY':
pass
else:
print data
convo=convo+'\n'+data
connection.sendall(convo)
except:
connection.close()
Here is the client:
import socket
import sys,os
name=raw_input("Enter name: ")
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('192.168.1.80', 10000)
print >>sys.stderr, 'connecting to %s port %s' % server_address
while True:
message=raw_input('Message: ')
try:
os.system('cls')
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(server_address)
if message is not '':
sock.sendall(name+": "+message)
else:
sock.sendall('EMPTY')
if message=='quit':
break
x=sock.recv(999)
print x
except:
break
sock.close()
Thanks!
If you need two operations to happen at the same time (the client script needs to read input from the user and read new messages from the server), then you'd need to either use threads (one thread for reading user input, and one for reading messages from the server), or futures (since python3.2).
Here's question for playing audio in python: Play audio with Python
As for your client, why are you reconnecting to your server every single time? Anyway, if I understand the problem correctly you're blocking on user input, but also want to handle messages from the server.
Without getting complicated with threads, I would recommended using a recurring signal, which I believe could handle this. There's a function call setitimer(), which will break what you're doing and call a function every so often then return to where you were (user input). In your timer function, check for server messages, print any received, play your sound and return to user input. There's an setitimer() example enter link description here.
Might be a little ugly with the user typing, so you may need to reprint what they're currently typing, but haven't sent out (using something other than raw_input()).
For a slightly more complicated option, which may help you there's a function call select(), which can block while listening for socket input AND user input. Then you just distinguish which is which and keep it all in one loop.
while True:
# select on server socket and user input (blocks for either one)
# if here, either a message has been received or the user typed something
# if a message from server
...
playSound()
# else
# send to server

Select API not waiting the specified timeout

I am doing a combination of Socket programming and pexpect in the same code. I have got it working but with a minor glitch. The select API waits for the specified 5 seconds in the first iteration. As soon as it received an input from the client it no longer waits for 5 seconds even though it is specified in the loop. In short after the first client server interaction takes place, select has no effect! I understand how to bypass this in C++ but I am comparatively new to Python and am unable to figure out the reason. I have attached the code below and is a pretty simple one.
#!/usr/bin/python
#Basic Functionailty: to create a process and to take inputs from client machines
#This input will be given to a background process which will display the user the parsed output
#using pexpect
import pexpect
import socket
import select
TCP_IP = '127.0.0.1'
TCP_PORT = 50050
BUFFER_SIZE = 1024
#spawning a pexpect process and printing everything before the prompt appears
child = pexpect.spawn('./pox.py')
child.expect ('POX>')
print child.before
#binding to a port number and acting as a server
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((TCP_IP, TCP_PORT))
server.listen(1)
input = [server]
#loop infinitely and get input and serve it to the process
#in addition to which if the process shows some messages display
#it to the user
while 1:
print 'Before select'
inputready,outputready,exceptready = select.select(input,[],[],5)
for s in inputready:
if s == server:
#if the input is from the server
conn, addr = s.accept()
print 'Connection address:', addr
input.append(conn)
data = conn.recv(BUFFER_SIZE)
if not data: continue
print "received data:", data
child.sendline (data)
else:
#if a time out occurs check the pexpect if it has any debug messages
i = child.expect ([pexpect.TIMEOUT, 'POX>'], timeout=1)
print child.before
if i == 0:
print child.before
You've modified input:
input.append(conn)
(and then called conn.recv to get some data, which will block until there is some data or EOF, but presumably there was some and you got it).
Having done that, on the next trip through the loop, it's likely that there is receive data, or EOF, ready for input on conn. I assume you immediately call child.expect (because s == conn and hence s != server). I'd bet that at this point, conn is at EOF, so that returns immediately, having done nothing. conn is still open, and still in input, so every time you call select it returns right away telling you that you can read another EOF from conn.

Categories

Resources