日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python编程16章_Python核心编程——Chapter16

發布時間:2025/3/21 python 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python编程16章_Python核心编程——Chapter16 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

好吧,在拜讀完《Python網絡編程基礎》之后,回頭再搞一搞16章的網絡編程吧。

Let‘s go!

16.4.修改書上示例的TCP和UDP客戶端,使得服務器的名字不要在代碼里寫死,要允許用戶指定一個主機名和端口。只有兩個值都沒有輸入是才使用默認值。

難度不大。

#tsTclnt.py#!/usr/bin/env python#-*-coding:utf-8-*-

from socket import *

importsysif(len(sys.argv) < 3):

HOST= 'localhost'PORT= 21567

else:

HOST= sys.argv[1]

PORT= int(sys.argv[2])

BUFSIZ= 1024ADDR=(HOST,PORT)

tcpCliSock=socket(AF_INET,SOCK_STREAM)

tcpCliSock.connect(ADDR)whileTrue:

data= raw_input('>')if notdata:breaktcpCliSock.send(data)

data=tcpCliSock.recv(BUFSIZ)if notdata:break

printdata

tcpCliSock.close()

#tsUclnt.py#!/usr/bin/env python#-*- coding:utf-8 -*-

from socket import *

importsysif(len(sys.argv) < 3):

HOST= 'localhost'PORT= 21567

else:

HOST= sys.argv[1]

PORT= sys.argv[2]#print sys.argv[1],sys.argv[2]

BUFSIZ= 1024ADDR=(HOST,int(PORT))

udpCliSock=socket(AF_INET,SOCK_DGRAM)whileTrue:

data= raw_input('>')if notdata:breakudpCliSock.sendto(data,ADDR)

data,ADDR=udpCliSock.recvfrom(BUFSIZ)if notdata:break

printdata

udpCliSock.close()

16.5.修改服務器示例代碼,使得它能根據不同的請求而作出應答。

這道題目本質上也不難,只需要在服務器的死循環程序加上條件判斷即可。

版本1:純TCP服務器端修改。

#!/usr/bin/env python#-*- coding:utf-8 -*-

from socket import *

importtime,os

HOST= ''PORT= 21567BUFSIZ= 1024ADDR=(HOST,PORT)

tcpSerSock=socket(AF_INET,SOCK_STREAM)

tcpSerSock.bind(ADDR)

tcpSerSock.listen(5)whileTrue:print 'waiting for connection...'tcpCliSock,addr=tcpSerSock.accept()print '...connected from:',addrwhileTrue:

data=tcpCliSock.recv(BUFSIZ)

data=data.strip()if notdata:break

if data == "date":

tcpCliSock.send('%s' %(time.ctime(time.time())))elif data == "os":

tcpCliSock.send('%s' %(os.name))elif data == "ls":

tcpCliSock.send('%s' %(os.listdir(os.curdir)))else:

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

tcpCliSock.close()

tcpSerSock.close()

版本2:使用現成的服務器框架進行修改。

#!/usr/bin/env python#-*-coding:utf-8-*-

from SocketServer importThreadingMixIn,TCPServer,StreamRequestHandlerimporttime,os,reclassTxRequestHandler(StreamRequestHandler):defhandle(self):

req=self.rfile.readline().strip()

m= re.match('(\w+)\s+([\w+/]+)',req)if req == "date":

result=time.ctime(time.time())elif req == "os":

result=os.nameelif req == "ls":

result=str(os.listdir(os.curdir))elif m is not None and m.lastindex == 2 and m.group(1) == 'ls':

result= str(os.listdir(m.group(2)))else:

result= """date -- 服務器將返回它的當前時間

os -- 得到操作系統的信息

ls -- 得到當前目錄的文件列表"""self.wfile.write(result+"\n")classTxServer(ThreadingMixIn,TCPServer):

allow_reuse_address= 1serveraddr= ('',8765)

srvr=TxServer(serveraddr,TxRequestHandler)

srvr.serve_forever()

16.7.實現一個半雙工的聊天方式,其中一個人是服務端,另一個人是客戶端。

其實也不難,只是將回射服務器做部分修改就可以。

服務器端:

#!/usr/bin/env python#-*- coding:utf-8 -*-

from socket import *

from time importctime

HOST= ''PORT= 21567BUFSIZ= 1024ADDR=(HOST,PORT)

tcpSerSock=socket(AF_INET,SOCK_STREAM)

tcpSerSock.bind(ADDR)

tcpSerSock.listen(5)whileTrue:print 'waiting for connection...'tcpCliSock,addr=tcpSerSock.accept()print '...connected from:',addrwhileTrue:

rdata=tcpCliSock.recv(BUFSIZ)if notrdata:break

printrdata

sdata= raw_input(">")

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

tcpCliSock.close()

tcpSerSock.close()

客戶端:

#!/usr/bin/env python#-*-coding:utf-8-*-

from socket import *

importsysif(len(sys.argv) < 3):

HOST= 'localhost'PORT= 21567

else:

HOST= sys.argv[1]

PORT= int(sys.argv[2])

BUFSIZ= 1024ADDR=(HOST,PORT)

tcpCliSock=socket(AF_INET,SOCK_STREAM)

tcpCliSock.connect(ADDR)whileTrue:

data= raw_input('>')if notdata:breaktcpCliSock.send(data)

data=tcpCliSock.recv(BUFSIZ)if notdata:break

printdata

tcpCliSock.close()

16.8.實現一個全雙工的聊天方式,即兩個人可以獨立地發送和接收消息。

全雙工其實原理也不太難,但是我一直傻逼了,一直用寫服務器端的方法去實現客戶端的程序。

我所使用的方法也是最常用的技術——多線程。以下是服務器端和客戶端的編寫思路:

服務器端:在服務器端我主要用了一個主線程來accept客戶端的鏈接,沒接受了一個連接,就新建兩個線程,一個用于發送消息,一個用于接收消息。

客戶端:思路完全不一樣,由于客戶端面對的只有服務器,所以主線程只能是接收消息(發送消息),然后發送消息(接收消息)作為一個線程來并發。

由于這里的數據并不是共享的,所以這里的線程寫起來就很輕松,不用考慮同步問題。

服務器端:

#!/usr/bin/env python#-*- coding:utf-8 -*-

importsocket,traceback,osfrom threading import *host= ''port= 51423 #監聽所有的接口

#接受消息的線程

defhandlerecv(clientsock):print "New child",currentThread().getName()print "Got connection from",clientsock.getpeername()whileTrue:

data= clientsock.recv(4096)if notlen(data):break

printdata

clientsock.close()#發送消息的線程

defhandlesend(clientsock):whileTrue:

data= raw_input(">")

data= data + "\n"; #加上換行,好看一點。

clientsock.sendall(data)#關閉連接

clientsock.close()#建立套接字

s =socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

s.bind((host,port))

s.listen(1)whileTrue:try:

clientsock,clientaddr=s.accept()exceptKeyboardInterrupt:raise

except:

traceback.print_exc()continuet= Thread(target = handlerecv,args=[clientsock])

t.setDaemon(1)

t.start()

r= Thread(target = handlesend,args=[clientsock])

r.setDaemon(1)

r.start()

客戶端:

#!/usr/bin/env python#-*-coding:utf-8-*-

from socket import *

importsysfrom threading import *

if(len(sys.argv) < 3):

HOST= 'localhost'PORT= 51423

else:

HOST= sys.argv[1]

PORT= int(sys.argv[2])

BUFSIZ= 1024ADDR=(HOST,PORT)defhandlesend(tcpCliSock):whileTrue:

sdata= raw_input('>')if notsdata:breaktcpCliSock.send(sdata)

tcpCliSock.close()

tcpCliSock=socket(AF_INET,SOCK_STREAM)

tcpCliSock.connect(ADDR)#建立發送消息的線程

s = Thread(target = handlesend,args=[tcpCliSock])

s.setDaemon(1)

s.start()whileTrue:

rdata=tcpCliSock.recv(BUFSIZ)if notrdata:break

printrdata

tcpCliSock.close()

16.10.實現一個多房間全雙工的聊天方式,把聊天服務器改成支持多用戶版本。

其實思路差不多,只不過過程有點繁瑣,在服務器端要建立字典,作為房間,然后每個套接字存在字典當中,然后作適當的分發。

另外一種方法使用廣播不知道可不可以了。

這里直接貼人家寫的代碼學習一下:

服務器端:

#!/usr/bin/env python#_*_ coding: utf8 _*_

from socket import *

from time importctimeimportthreadingfrom string importsplit

HOST= ''PORT= 21567BUFSIZE= 1024ADDR=(HOST, PORT)defDeal(sck, username, room):whileTrue:

data=sck.recv(BUFSIZE)for i inclients[room].iterkeys():if i <>username:if data <> "quit":

clients[room][i].send("[%s] %s: %s" %(ctime(), username, data))else:

clients[room][i].send("用戶%s在%s退出房間%s" %(username, ctime(), room ))if data == "quit":delclients[room][username]

sck.send(data)

sck.close()breakchatSerSock=socket(AF_INET, SOCK_STREAM)

chatSerSock.bind(ADDR)

chatSerSock.listen(5)

clients= {"":{},}whileTrue:print 'waiting for connection...'chatCliSock, addr=chatSerSock.accept()print "...connected romt:", addr

data=chatCliSock.recv(BUFSIZE)

username, room=split(data)printusernameif notclients.has_key(room):

clients[room]={}ifclients[room].has_key(username):

chatCliSock.send("reuse")

chatCliSock.close()else:

chatCliSock.send("success")

clients[room][username]=chatCliSock

t= threading.Thread(target=Deal, args=(chatCliSock, username, room))

t.start()

chatSerSock.close()

客戶端:

#!/usr/bin/env python#_*_ coding: utf8 _*_

from socket import *

from time importctimeimportthreadingimportrandomfrom sys importargv, exit, stdoutfrom getopt importgnu_getopt, GetoptError

help_info= ["cs.py [ -h | --help | -u | --username] username","\t-h or --help\t顯示幫助信息","\t-u or --username\指定用戶名","\t-r or --room\t指定房間"]defhelp():for i inhelp_info:printidefSend(sck, test):whileTrue:

data= raw_input('>')

sck.send(data)if data == "quit":break

defRecieve(sck, test):whileTrue:

data=sck.recv(BUFSIZ)if data == "quit":

sck.close()breakstr= "\n" + data + "\n>"stdout.write(str)

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

threads=[]if __name__ == "__main__":#解析命令行參數

try:

opts, args= gnu_getopt(argv[1:], "hu:r:", ["help", "username=", "room="])exceptGetoptError, err:printstr(err)

help()

exit(2)

username= ""room= ""

for o, a inopts:if o in ("-h", "--help"):

help()

exit(0)elif o in ("-u", "--username"):

username=aelif o in ("-r", "--room"):

room=aelse:print "未知選項"help()

exit(2)if not username or notroom:

help()

exit(2)

chatCliSock=socket(AF_INET, SOCK_STREAM)

chatCliSock.connect(ADDR)

chatCliSock.send("%s %s" %(username, room))

data=chatCliSock.recv(BUFSIZ)if data == "reuse":print "用戶%s已登錄房間%s" %(username, room)

raw_input()

exit(1)elif data == "success":print "用戶%s成功登錄房間%s" %(username, room)

t= threading.Thread(target=Send, args =(chatCliSock, None))

threads.append(t)

t= threading.Thread(target=Recieve, args =(chatCliSock, None))

threads.append(t)for i inrange(len(threads)):

threads[i].start()

threads[0].join()

16.11.寫一個網頁客戶端。自己新建一個套接字,然后發送http請求。

感覺難度不大。

#!/usr/bin/env python#-*-coding:utf-8-*-

importsocket,sys

website= sys.argv[1]

port= 80

printwebsiteprint "Creating socket...",

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)print "done."

print "Connecting to ...",

s.connect((website,port))print "done."s.send("GET /index.html HTTP/1.0\r\n\r\n")

data= s.recv(4096)print data

16-12.休眠服務器,在服務器端上面加個sleep(num)就好,在這里就不貼了。

16-13.功能太過復雜,本人渣渣,沒精力寫。

16-14.考慮的東西很多,水平有限,不做了。

16-15.異步和SocketServer。這個用多線程可以實現,在《python網絡編程基礎》上面直接有源碼。使用方法都有教。

#!/usr/bin/env python#-*- coding:utf-8 -*-

from SocketServer importThreadingMixIn,TCPServer,StreamRequestHandlerimporttimeclassTimeRequestHandler(StreamRequestHandler):defhandle(self):

req=self.rfile.readline().strip()if req == "asctime":

result=time.asctime()elif req == "seconds":

result=str(int(time.time()))elif req == "rfc822":

result= time.strftime("%a, %d %b %Y %H:%M:%S +0000",time.gmtime())else:

result= """Unhandled request.Send a line with one of the following words:

asctime -- for human-readable time

seconds -- seconds since the Unix Epoch

rfc822 -- data/time in format used for mail and news posts"""self.wfile.write(result+ "\n")classTimeServer(ThreadingMixIn,TCPServer):

allow_reuse_address= 1serveraddr= ('',8765)

srvr=TimeServer(serveraddr,TimeRequestHandler)

srvr.serve_forever()

多多指教!謝謝!

總結

以上是生活随笔為你收集整理的python编程16章_Python核心编程——Chapter16的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。