Python 套接字服务器/客户端编程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18971777/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python socket server/client programming
提问by Katie Jurek
So I am just getting into python and trying out some stuff. To start, I am making a server that does simple stuff like "GET"s stored text, "STORE"s new text over the old stored text, and "TRANSLATE"s lowercase text into uppercase. But I have a few questions. Here is my code so far:
所以我刚刚进入 python 并尝试一些东西。首先,我正在制作一个服务器,它可以执行简单的操作,例如“GET”的存储文本、“STORE”的新文本覆盖旧的存储文本,以及“TRANSLATE”的小写文本转换为大写。但我有几个问题。到目前为止,这是我的代码:
import socket
HOST = '' # Symbolic name meaning the local host
PORT = 24069 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
s.bind((HOST, PORT))
except socket.error , msg:
print 'Bind failed. Error code: ' + str(msg[0]) + 'Error message: ' + msg[1]
sys.exit()
print 'Socket bind complete'
s.listen(1)
print 'Socket now listening'
while 1:
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
data = conn.recv(1024)
reply = 'OK...' + data
if not data: break
conn.send(data)
conn.close()
s.close()
To start changing text from a client into uppercase, from my other programming knowledge, I assume I'd store the client's text in a variable and then run a function on it to change it to uppercase. Is there such a function in python? Could someone please give me a snippet of how this would look?
为了开始将文本从客户端更改为大写,根据我的其他编程知识,我假设我将客户端的文本存储在一个变量中,然后在其上运行一个函数以将其更改为大写。python中有这样的函数吗?有人可以给我一个片段,说明它的外观吗?
And lastly, how would I do something like a GET or STORE in python? My best guess would be:
最后,我将如何在 python 中执行诸如 GET 或 STORE 之类的操作?我最好的猜测是:
data = conn.recv(1024)
if data == GET: print text
if data == STORE: text = data #Not sure how to reference the text that the client has entered
Thank you so much for any help! :)
非常感谢您的帮助!:)
Note to self:
注意自我:
import socket
HOST = '' # Symbolic name meaning the local host
PORT = 24069 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
s.bind((HOST, PORT))
except socket.error , msg:
print 'Bind failed. Error code: ' + str(msg[0]) + 'Error message: ' + msg[1]
sys.exit()
print 'Socket bind complete'
s.listen(1)
print 'Socket now listening'
# Accept the connection
(conn, addr) = s.accept()
print 'Server: got connection from client ' + addr[0] + ':' + str(addr[1])
storedText = 'Hiya!'
while 1:
data = conn.recv(1024)
tokens = data.split(' ', 1)
command = tokens[0]
if command == 'GET':
print addr[0] + ':' + str(addr[1]) + ' sends GET'
reply = storedText
elif command == 'STORE':
print addr[0] + ':' + str(addr[1]) + ' sends STORE'
storedText = tokens[0]
reply = '200 OK\n' + storedText
elif command == 'TRANSLATE':
print addr[0] + ':' + str(addr[1]) + ' sends TRANSLATE'
storedText = storedText.upper()
reply = storedText
elif command == 'EXIT':
print addr[0] + ':' + str(addr[1]) + ' sends EXIT'
conn.send('200 OK')
break
else:
reply = '400 Command not valid.'
# Send reply
conn.send(reply)
conn.close()
s.close()
采纳答案by justhalf
I see that you're quite new to Python. You can try to find some code example, and you shouldalso learn how to interpret the error message. The error message will give you the line number where you should look at. You should consider that line or previous line, as the error may be caused by previous mistakes.
我发现您对 Python 很陌生。您可以尝试查找一些代码示例,您还应该了解如何解释错误消息。错误消息将为您提供应该查看的行号。您应该考虑该行或前一行,因为错误可能是由以前的错误引起的。
Anyway, after your edits, do you still have indentation error?
无论如何,在您编辑之后,您是否仍然有缩进错误?
On your real question, first, the concept.
关于你真正的问题,首先是概念。
To run client/server, you'll need two scripts: one as the client and one as the server.
要运行客户端/服务器,您需要两个脚本:一个作为客户端,一个作为服务器。
On the server, the script will just need to bind to a socket and listen to that connection, receive data, process the dataand then return the result. This is what you've done correctly, except that you just need to process the data before sending response.
在服务器上,脚本只需要绑定到一个套接字并侦听该连接、接收数据、处理数据然后返回结果。这是您正确完成的操作,只是您只需要在发送响应之前处理数据。
For starter, you don't need to include the accept
in the while loop, just accept one connection, then stay with it until client closes.
首先,您不需要accept
在 while 循环中包含 ,只需接受一个连接,然后一直使用它直到客户端关闭。
So you might do something like this in the server:
所以你可以在服务器中做这样的事情:
# Accept the connection once (for starter)
(conn, addr) = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
stored_data = ''
while True:
# RECEIVE DATA
data = conn.recv(1024)
# PROCESS DATA
tokens = data.split(' ',1) # Split by space at most once
command = tokens[0] # The first token is the command
if command=='GET': # The client requests the data
reply = stored_data # Return the stored data
elif command=='STORE': # The client want to store data
stored_data = tokens[1] # Get the data as second token, save it
reply = 'OK' # Acknowledge that we have stored the data
elif command=='TRANSLATE': # Client wants to translate
stored_data = stored_data.upper() # Convert to upper case
reply = stored_data # Reply with the converted data
elif command=='QUIT': # Client is done
conn.send('Quit') # Acknowledge
break # Quit the loop
else:
reply = 'Unknown command'
# SEND REPLY
conn.send(reply)
conn.close() # When we are out of the loop, we're done, close
and in the client:
并在客户端:
import socket
HOST = '' # Symbolic name meaning the local host
PORT = 24069 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST,PORT))
while True:
command = raw_input('Enter your command: ')
if command.split(' ',1)[0]=='STORE':
while True:
additional_text = raw_input()
command = command+'\n'+additional_text
if additional_text=='.':
break
s.send(command)
reply = s.recv(1024)
if reply=='Quit':
break
print reply
Sample run (first run the server, then run the client) on client console:
在客户端控制台上运行示例(首先运行服务器,然后运行客户端):
Enter your command: STORE this is a text OK Enter your command: GET this is a text Enter your command: TRANSLATE THIS IS A TEXT Enter your command: GET THIS IS A TEXT Enter your command: QUIT
I hope you can continue from there.
我希望你能从那里继续。
Another important point is that, you're using TCP (socket.SOCK_STREAM
), so you can actually retain the connection after accepting it with s.accept()
, and you should only close it when you have accomplished the task on that connection (accepting new connection has its overhead). Your current code will only be able to handle single client. But, I think for starter, this is good enough. After you've confident with this, you can try to handle more clients by using threading.
另一个重要的一点是,您使用的是 TCP ( socket.SOCK_STREAM
),因此您实际上可以在用 接受连接后保留连接s.accept()
,并且只有在完成该连接上的任务后才应关闭它(接受新连接有其开销)。您当前的代码将只能处理单个客户端。但是,我认为首先,这已经足够了。在您对此充满信心后,您可以尝试使用threading来处理更多客户端。