您的位置:首页 > 理论基础 > 计算机网络

Python 网络编程---简单的服务器与客户端实现---阻塞式编写

2013-11-25 19:45 1186 查看
这个是教材《Python核心编程第二版》第16章的代码,如果一点不变动的敲入,会发总是出现问题,整了一些时间才弄好,下边说一下遇到的问题以及解决方法:

首先把运行成功的代码贴出来一下:

服务端代码:运行在python3.3上

#!/usr/bin.env python
# -*- coding: cp936 -*-
from socket import *
from time import ctime
def serverSocket():
HOST    = 'localhost'   #主机地址
PORT    = 21567         #服务器接收端口
BUFSIZ  = 1024          #接收套接字的缓冲区大小
ADDR    = (HOST, PORT)  #仅仅是将二者合起来,作为连接到的服务器地址类型

tcpSerSock = socket(AF_INET , SOCK_STREAM) #udpSerSock = socket(AF_INET , SOCK_DGRAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)

while True:
print ('waiting for connection...')
tcpCliSock, address = tcpSerSock.accept()

print ('connected from :', address)

while True:
recvData = tcpCliSock.recv(BUFSIZ)
if not recvData:
print ('no found data')
break
tcpCliSock.send(('[%s] %s'%(ctime(), recvData)).encode('utf-8'))
tcpCliSock.close()
tcpSerSock.close()

def main():
serverSocket()

if __name__ == '__main__':
main()
客户端代码:运行在python2.7上

#!/usr/bin/env python

from socket import *

def clientSocket():
HOST    = 'localhost'
PORT    = 21567
BUFSIZ  = 1024
ADDR    = (HOST, PORT)

tcpCliSock = socket(AF_INET , SOCK_STREAM)
tcpCliSock.connect(ADDR)

while True:
data = raw_input('input :')
print (data)
if not data:
break
tcpCliSock.send(data.encode('utf-8'))
data = tcpCliSock.recv(BUFSIZ)
if not data:
break
print (data)
tcpCliSock.close()

def main():
clientSocket()

if __name__ == '__main__':
main()

首先说一下我为啥使用两个版本的python,如果使用一个版本的python,就要使用命令行,让两个脚本在不同的命令行窗体中输入,否则使用IDLE的F5的时候,发现客户端的输入,服务端根本没有反应。放在两种上之后,F5后运行在不用输入窗体中,就可以两边单独运行。

好了,接下来说一下源码中的细节问题:

首先是服务器源码,

001:tcpCliSock.close()

这行不应该与源码中那样在与第二层循环中,应该向前一个tab,否则循环的时候,就会出现:

    recvData = tcpCliSock.recv(BUFSIZ)

OSError: [WinError 10038] 在一个非套接字上尝试了一个操作。

002:tcpCliSock.send(('[%s] %s'%(ctime(), recvData)).encode('utf-8'))

对于send函数,里边不能是字符串形式,如果不转化,发现提示问题是:

    tcpCliSock.send(('[%s] %s'%(ctime(), recvData)))

TypeError: 'str' does not support the buffer interface


帮助文档是这样的:

socket.send(bytes[,
flags])

Send data to thesocket. Thesocket must be connected to a remotesocket.
The optional flags argument has the same meaning as forrecv()
above. Returns the number of bytes sent. Applications are responsible for checking that all data has been sent; if only some of the data was transmitted, the application needs to attempt delivery of the remaining data. For further information on this topic,
consult theSocket Programming HOWTO.


有一个例子:

>>> import socket
>>> s1, s2 = socket.socketpair()
>>> b1 = bytearray(b'----')
>>> b2 = bytearray(b'0123456789')
>>> b3 = bytearray(b'--------------')
>>> s1.send(b'Mary had a little lamb')

其实我们不是一定要使用这种形式,我尝试了一下,这样:

tcpCliSock.send(data.encode('utf-8'))

或者tcpCliSock.send(data.encode('ascii'))都可以,同理,客户端也应该将send函数里边做这样的处理。

003:

客户端输入的地方出现的问题:

如果这样:data = input('input :')(之所以会写成这样主要是因为中途换成3.3版本的,在那不能使用raw_input())

结果输入字符串的时候报错:

    data = input('input :')

  File "<string>", line 1, in <module>

NameError: name 'sdfsd' is not defined


而输入数字的时候又是另外的错误:

    tcpCliSock.send(data.encode('utf-8'))

AttributeError: 'int' object has no attribute 'encode'


我很是不解上边的是为什么,在2.7下还是使用raw_input(),这个没问题,在3.3下使用input(),以后使用的时候也要特别注意这个版本问题。

如果对我的理解有什么不同见解非常欢迎提出,毕竟我是初学者,一定会有不少理解不到位的地方,一起加油啊~!

运行结果贴图:





在此感谢一些网友之前的疑问以及解答:

TypeError: 'str' does not support the buffer interface

Python socket编程 
Windows Socket API 使用经验 
[D]python写的服务器和客户端 [问题点数:120分,结帖人mzy666888]
 [D]python写的服务器和客户端,该如何解决
python error: [Errno 10061]
windous socket error:在一个非套接字上尝试了一个操作。(10038),on API getpeern

python编程input与raw_input
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python