473,465 Members | 1,860 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Client/Server socket send user input

jas
I have a basic client/server socket situation setup....where the server
accepts a connection and then waits for commands.

On the client side, I create a socket, connect to the server...then I
pass the socket to a class which just reads from the socket (in a
thread).

class Reader(Thread):
def run(self):
while 1:
print self.sock.recv(1),

Now, when the server sends back a message, and needs input back the
reader hangs at the sock.recv line...which is fine, and expected.
However, I want to be able to type something into the console at that
point and hit enter, and have it sent to the server.

In my client class I tried something like...

class Client(Thread):
def run(self):
reader = Reader(self.sock)
reader.start()
while 1:
x = raw_input("go>")
self.sock.send(x)
print "sent", x

However, in order to see "go>" ..I have to hit enter first, then type
in my command and hit enter to send. I just want to type and hit
enter.

Any ideas/suggestions?

Thanks.

Oct 25 '05 #1
4 9404
jas
I even tried inserting a "\r" or "\r\n" or "\n" to stdout, also tried
the same using msvcrt.putch() ...but no luck. I still have to hit
enter to get the prompt , where I can then type a command and hit
enter.

For example, I get this displayed:
[example]
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\>[cursor_is_here]
[/example]

....so I type something like.."ver" but I get

[example]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'ver' is not defined
[/example]

Now, if I start over and have...

[example]
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\>[cursor_is_here]
[/example]

...and I press the Enter key I end up with

[example]
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\>
[cursor_is_here]

[/example]

So, I get the prompt, I hit enter, which then displays the ">>>" ..and
if I type "ver" there, I get back what I expect.

I just wish I didn't have to hit enter before being able to type a
command.

Oct 25 '05 #2
On 25 Oct 2005 12:39:06 -0700, "jas" <co*******@gmail.com> declaimed the
following in comp.lang.python:

Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'ver' is not defined
[/example]


That >>> tells us that you are running inside the interactive PYTHON
interpreter. That means you now have TWO processes trying to read from
the SAME keyboard/console window, and they are likely going to be taking
turns... Python is going to put out its prompt while the subprocess is
starting, and queues ITS read statement -- the subprocess then puts out
ITS prompt and queues a read. You type something, and the FIRST read
sees it -- the Python interactive interpreter.

Here's the latest mod on my massive test sample... No changes to the
"shell" class -- it was already rigged to pipe data in both directions
(the subprocess is NOT trying to read the keyboard/console). Instead of
passing in canned test commands I now made a loop that does a "capture"
until "None" is returned (time-out), then the PYTHON program prompts for
a command to be sent on to the subprocess.

-=-=-=-=-=-=-=-=-
import subprocess
import os
import threading
import Queue
class Shell(object):
def __init__(self, command):
# flag for shutdown
self.die = False

self.timeOut = 1.0

# queue for buffering "lines"
self.lineQueue = Queue.Queue()

# list for collecting characters read from subprocess
# allows for character reader to collect characters
# while line reader processes a prior batch
self.charList = []

# event to signal that, at least, one character is
# available. event is used to allow time-out wait()
self.charEvent = threading.Event()

# event to signal that something has been written to the
# subprocess, and that the line reader should start
# collecting stuff (this is used to avoid multiple "prompt"
# timeouts from falsely affecting the user
self.lineEvent = threading.Event()

# lock to wrap access to self.charList
self.charLock = threading.Lock()

# create subprocess object with supplied command
self.process = subprocess.Popen(command,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE)

# initialize, and start the character reader
# thread -- this is the thread that actually reads the
# subprocess output stream, one character at a time
self.charThread = threading.Thread(target=self.readChar)
self.charThread.start()

# initialize, and start the line reader thread
# -- this is the thread that processes collected characters
# OR on a timeout of the event, queues up a prompt and
# then busy-waits until the queue is empty (meaning the
# user application has processed up to
self.lineThread = threading.Thread(target=self.readLine)
self.lineThread.start()

# set the line event so the line reader knows it should read
up
# to the next time-out/prompt
self.lineEvent.set()

def readChar(self):
while not self.die:
# read one character at a time from subprocess; blocks
ch = self.process.stdout.read(1)

# get the lock to access the character list, append it
self.charLock.acquire()
self.charList.append(ch)
# signal the line reader that, at least one, character
# is in the list
self.charEvent.set()
# let the line reader access the character list
self.charLock.release()

def readLine(self):
lineChar = []
while not self.die:
# block until told that the subprocess has been commanded
# and thereby should be producing some sort of output
self.lineEvent.wait()
# block for up to one second waiting for the character
# reader to produce some sort of output
self.charEvent.wait(self.timeOut)
# get the lock allowing access to the character list
self.charLock.acquire()
# clear the character reader event so the next pass
# will block(time-out) if no more data
self.charEvent.clear()
# save the character list locally so the character reader
# can add more stuff to it (after clearing it)
tCharList = self.charList
self.charList = []
# release the character list lock so reader can touch it
self.charLock.release()
# if the list is not empty, we have some data
if tCharList:
# process each character looking for a new line
character
# note: no filtering is done, all characters will be
# returned to user
for ch in tCharList:
lineChar.append(ch)
# on a new line, collect all preceding and make a
# string out of them, queue the string
if ch == "\n":
self.lineQueue.put("".join(lineChar))
lineChar = []
else:
# time out, assume prompt stage, queue partial line
self.lineQueue.put("".join(lineChar))
lineChar = []
# queue None as signal
self.lineQueue.put(None)
# AND clear the line event so we don't try to read
# anymore data (and get time-out/prompts) until the
# user has sent some command
self.lineEvent.clear()

def input(self):
# return the next available data line (which may be None for
# time-out/prompt. This will BLOCK if called when the queue
# is empty
return self.lineQueue.get()

def empty(self):
# return the state of the line queue
return self.lineQueue.empty()

def send(self, data, timeout = 1.0):
# send the data to the subprocess
self.process.stdin.write(data)
# reset the timeout value -- this allows the user to specify
# a long timeout for known number crunchers so that one
# doesn't get an errorneous (early) "prompt" indication
self.timeOut = timeout
# signal the line reader that data has been sent, and it
# should start processing return data
self.lineEvent.set()

def shutdown(self):
self.die = True
self.charEvent.set()
self.charThread.join()
self.lineEvent.set()
self.lineThread.join()
myCommand = Shell("cmd.exe")

while True:
try:
print "\n***** Start capture"
while True:
ln = myCommand.input()
if not ln: break
print ln,
print "\n***** End capture"
UserData = raw_input("\nApplication Prompt (<ctrl-z> to exit)>
")
myCommand.send(UserData + "\n")
except:
break

myCommand.send("exit\n")

myCommand.shutdown()

-=-=-=-=-=-=-

E:\UserData\Dennis Lee Bieber\My Documents>python script2.py

***** Start capture
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

E:\UserData\Dennis Lee Bieber\My Documents>
***** End capture

Application Prompt (<ctrl-z> to exit)> dir

***** Start capture
dir
Volume in drive E is Data
Volume Serial Number is 2626-D991

Directory of E:\UserData\Dennis Lee Bieber\My Documents

10/25/2005 09:03 PM <DIR> .
10/25/2005 09:03 PM <DIR> ..
07/25/2005 10:39 PM <DIR> .metadata
10/06/2005 09:54 AM <DIR> Ada Progs
08/13/2005 02:01 PM <DIR> Agent Data
10/21/2005 09:29 AM 421,820 apress_offer.pdf
07/03/2005 11:36 AM 132 cp.py
07/17/2005 12:25 PM <DIR> Cyberlink
07/06/2005 09:32 AM 102,400 db1.mdb
07/26/2005 12:20 AM 26,614 eclipse_code.xml
10/25/2005 08:06 PM <DIR> Eudora
06/24/2005 08:50 PM 667 fake_oosums.ads
06/24/2005 08:50 PM 695 fake_oosums.ali
09/06/2005 09:01 PM <DIR> Genealogy
07/13/2005 10:56 PM <DIR> HomeSite
05/08/2005 01:05 PM <DIR> Investing
10/21/2005 10:04 PM <DIR> Java Progs
08/04/2005 10:13 PM 162 main.py
10/11/2005 10:43 PM <DIR> My Downloads
05/01/2005 10:31 AM <DIR> My eBooks
04/22/2005 12:09 AM <DIR> My Music
07/10/2005 11:43 AM <DIR> My Pictures
06/29/2005 11:55 PM <DIR> My PSP Files
05/23/2005 09:30 AM <DIR> My Videos
05/01/2005 12:49 PM <DIR> Office Documents
06/27/2005 03:19 PM 7,961,778
org.eclipse.jdt.doc.user.I20050627-1435.pdf
06/27/2005 03:19 PM 6,791,109
org.eclipse.platform.doc.user.I20050627-1435.pdf
10/11/2005 10:52 PM 56 oth_tsr_rm_750.ram
07/20/2005 09:32 AM 108,457 parkerred15yc.jpg
09/03/2005 10:36 PM <DIR> Python Progs
10/25/2005 08:16 PM <DIR> Quicken
07/10/2005 12:09 PM 3,356,248 results.xml
06/11/2005 12:03 PM 935 Scout_Ship Database.lnk
07/03/2005 12:38 PM <DIR> Scout_Ship My Documents
10/24/2005 09:23 AM 971 Script1.py
09/25/2005 12:40 PM 1,107 Script1_old.py
10/25/2005 09:03 PM 6,352 Script2.py
08/28/2005 11:47 AM <DIR> SimpleMu Logs
06/24/2005 08:56 PM 1,201 student_pack.ads
06/24/2005 08:49 PM 1,144 student_pack.ads.0
06/24/2005 08:56 PM 1,342 student_pack.ali
08/02/2005 11:39 PM 4,096 t.DOC
06/20/2005 10:11 AM 104 t.rx
08/05/2005 08:41 PM 66,452 Untitled-1.tif
08/05/2005 08:41 PM <DIR> VCheck
10/03/2005 02:58 AM <DIR> Visual Studio
10/03/2005 02:51 AM <DIR> Visual Studio 2005
22 File(s) 18,853,842 bytes
25 Dir(s) 267,148,263,424 bytes free

E:\UserData\Dennis Lee Bieber\My Documents>
***** End capture

Application Prompt (<ctrl-z> to exit)> time

***** Start capture
time
The current time is: 21:04:25.74
Enter the new time:
***** End capture

Application Prompt (<ctrl-z> to exit)>

***** Start capture
E:\UserData\Dennis Lee Bieber\My Documents>
***** End capture

Application Prompt (<ctrl-z> to exit)> ^Z

E:\UserData\Dennis Lee Bieber\My Documents>
-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <

Oct 26 '05 #3
jas
Dennis,
Thanks. That certainly looks like it could work. I understand
about the interactive shell and my app going back and forth with the
reads/writes. When my program runs it won't be used in an interactive
python shell, but that is the only way I know of to really test it.

Oct 26 '05 #4
On 26 Oct 2005 04:49:20 -0700, "jas" <co*******@gmail.com> declaimed the
following in comp.lang.python:
Dennis,
Thanks. That certainly looks like it could work. I understand
about the interactive shell and my app going back and forth with the
reads/writes. When my program runs it won't be used in an interactive
python shell, but that is the only way I know of to really test it.
Do what I do... Open a command shell, and run from there using a
simple "python whatever.py"; just use IDLE or PythonWin for editing,
saving the file before each test.

-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <

Oct 26 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
by: Michael Rybak | last post by:
hi, everyone. I'm writing a 2-players game that should support network mode. I'm now testing it on 1 PC since I don't have 2. I directly use sockets, and both client and server do...
9
by: craig.overton | last post by:
All, I am currently developing an FTP class in VB.NET. It's kid tested, mother approved when trying to access an FTP Server on a Windows box meaning I can connect, run commands, upload and...
1
by: bobano | last post by:
Hi everyone, I am writing a POP3 Client program in Perl. You connect to a POP3 Server and have a running conversation with the mail server using commands from the RFC 1939 Post Office Protocol....
3
by: khu84 | last post by:
Here is client server very simple code, seems to work with telnet but with with web client code gives blank output. Following is the server code:- <? function...
2
by: nsaffary | last post by:
hi I hava a client/server program that run correctly when i run it in one computer(local) but when I run client on a one computer and run server run on another, connection does not stablish.(I set...
0
by: sarahnetworking | last post by:
Hello, I have developed a client server application using C. i have a list of usernames and a list of passwords in a text file. i need to be able to do 2 loops so i can send the usernames and...
3
by: dynamo08 | last post by:
Hi, I am new to socket programming, I wrote an ftpclient which connects to an ftp server and downloads a file to the client computer. Now in one client connection I want to download multiple files...
10
by: Elaine121 | last post by:
Hi i've been batteling for hours and can't seem to find the problem. When my server runs and I press the connect button the gui freezes until the client gui is terminated.. only then the gui becomes...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.