|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
欢迎大家来到仓酷云论坛!python编写server的步调:
- 第一步是创立socket对象。挪用socket结构函数。如:
socket=socket.socket(family,type)
family参数代表地址家族,可为AF_INET或AF_UNIX。AF_INET家族包含Internet地址,AF_UNIX家族用于统一台机械上的过程间通讯。
type参数代表套接字类型,可为SOCK_STREAM(流套接字)和SOCK_DGRAM(数据报套接字)。
- 第二步是将socket绑定到指定地址。这是经由过程socket对象的bind办法来完成的:
socket.bind(address)
由AF_INET所创立的套接字,address地址必需是一个双元素元组,格局是(host,port)。host代表主机,port代表端标语。假如端标语正在应用、主机名不准确或端口已被保存,bind办法将激发socket.error异常。
- 第三步是应用socket套接字的listen办法吸收衔接要求。
socket.listen(backlog)
backlog指定最多许可若干个客户衔接到办事器。它的值至多为1。收到衔接要求后,这些要求须要列队,假如队列满,就谢绝要求。
- 第四步是办事器套接字经由过程socket的accept办法期待客户要求一个衔接。
connection,address=socket.accept()
调用accept办法时,socket会时入“waiting”状况。客户要求衔接时,办法树立衔接并前往办事器。accept办法前往一个含有两个元素的元组(connection,address)。第一个元素connection是新的socket对象,办事器必需经由过程它与客户通讯;第二个元素address是客户的Internet地址。
- 第五步是处置阶段,办事器和客户端经由过程send和recv办法通讯(传输数据)。办事器挪用send,并采取字符串情势向客户发送信息。send办法前往已发送的字符个数。办事器应用recv办法从客户吸收信息。挪用recv时,办事器必需指定一个整数,它对应于可经由过程本次办法挪用来吸收的最年夜数据量。recv办法在吸收数据时会进入“blocked”状况,最初前往一个字符串,用它表现收到的数据。假如发送的数据量跨越了recv所许可的,数据会被截短。过剩的数据将缓冲于吸收端。今后挪用recv时,过剩的数据会从缓冲区删除(和自前次挪用recv以来,客户能够发送的其它任何数据)。
- 传输停止,办事器挪用socket的close办法封闭衔接。
python编写client的步调:
- 创立一个socket以衔接办事器:socket=socket.socket(family,type)
- 应用socket的connect办法衔接办事器。关于AF_INET家族,衔接格局以下:
socket.connect((host,port))
host代表办事器主机名或IP,port代表办事器过程所绑定的端标语。如衔接胜利,客户便可经由过程套接字与办事器通讯,假如衔接掉败,会激发socket.error异常。
- 处置阶段,客户和办事器将经由过程send办法和recv办法通讯。
- 传输停止,客户经由过程挪用socket的close办法封闭衔接。
上面给个简略的例子:
server.py
python代码
client.py
python代码
在终端运转server.py,然后运转clien.py,会在终端打印“welcometoserver!"。假如更改client.py的sock.send(1)为其它值在终端会打印”pleasegoout!“,更改time.sleep(2)为年夜于5的数值,办事器将会超时。
tcp通讯图
上图是一张socket的tcp通讯简图,我们都晓得tcp的通讯须要三次握手。tcp是靠得住的、面向衔接的、努力传输的协定,而udp是弗成靠的、面向非衔接的、不努力传输的协定。然则弗成靠不代表它没有效,udp有本身的运用场景,语音和视频简直都在应用udp协定,它的弗成靠只是相对tcp来讲的,然则它的利益就是效力,高效在某些场景要比靠得住性主要。这就触及trade-off了,也就是衡量,须要依据你的运用衡量利害,然落后行选择。
在socket选择初始化一个tcp协定的socket以后,就会绑定一个地址和端口,然后开端listen,客户端衔接这个listen的tcp以后,办事端会accept这个要求,然后发生一个新的socket,两边应用这个新的socket(地址和端口,地址照样下面listen的地址,端口会是一个新的,这个从打印出的成果中可以看出)停止后续的通讯。本来的端口会持续的listen新的要求。
上面是tcpServer的代码
- importsocketHOST=192.168.0.37PORT=50000BUFFER=4096sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)sock.bind((HOST,PORT))sock.listen(0)print(tcpServerlistenat:%s:%s
- %(HOST,PORT))whileTrue:client_sock,client_addr=sock.accept()print(%s:%sconnect%client_addr)whileTrue:recv=client_sock.recv(BUFFER)ifnotrecv:client_sock.close()breakprint([Client%s:%ssaid]:%s%(client_addr[0],client_addr[1],recv))client_sock.send(tcpServerhasreceivedyourmessage)sock.close()
复制代码 socket.SOCK_STREAM是用来指定socket是基于tcp协定的。
上面是对应的客户端代码
- importsocketHOST=192.168.0.37PORT=50000BUFFER=4096sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)sock.connect((HOST,PORT))sock.send(hello,tcpServer!)recv=sock.recv(BUFFER)print([tcpServersaid]:%s%recv)sock.close()
复制代码
上面是udpServer的代码
- importsocketHOST=192.168.0.37PORT=50001BUFFER=4096sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)sock.bind((HOST,PORT))#sock.listen(0)print(tcpServerlistenat:%s:%s
- %(HOST,PORT))whileTrue:#client_sock,client_addr=sock.accept()#print(%s:%sconnect%client_addr)whileTrue:recv,client_addr=sock.recvfrom(BUFFER)ifnotrecv:breakprint([Client%s:%ssaid]:%s%(client_addr[0],client_addr[1],recv))sock.sendto(tcpServerhasreceivedyourmessage,client_addr)
复制代码- 你会发明因为udp长短衔接的,不须要三次握手,所以不须要停止listen,也不须要accept,直接通讯就能够了。还有就是初始化socket的时刻,经由过程指定
复制代码 [/code]- 来完成初始化的socket是基于udp协定的。假如初始化的是udp协定的socket,就不须要listen,也不存在accept,两边通讯的同时指明对方的地址和端口就能够了。对应的客户端代码:
复制代码- #!/usr/bin/envpython#-*-coding:UTF-8-*-importsocketHOST=192.168.0.37PORT=50001BUFFER=4096sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)sock.connect((HOST,PORT))sock.send(hello,tcpServer!)recv=sock.recv(BUFFER)print([tcpServersaid]:%s%recv)sock.close()
复制代码 [/code]- Server:[python]viewplaincopyprint?#serverimportsocketaddress=(127.0.0.1,31500)s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#s=socket.socket()s.bind(address)s.listen(5)ss,addr=s.accept()printgotconnectedfrom,addrss.send(byebye)ra=ss.recv(512)printrass.close()s.close()Client:[python]viewplaincopyprint?#clientimportsocketaddress=(127.0.0.1,31500)s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.connect(address)data=s.recv(512)printthedatareceivedis,datas.send(hihi)s.close()
复制代码 </p>运转成果:
server
[work@db-testing-com06-vm3.db01.百度.compython]$pythonserver.py
gotconnectedfrom(127.0.0.1,47872)
hihi
client
[work@db-testing-com06-vm3.db01.百度.compython]$pythonclient.py
thedatareceivedisbyebye
==============================================================================
参考材料:http://www.cppblog.com/lai3d/archive/2008/02/19/42919.html
一个简略的办事器和客户端通讯的例子
办事器:
importsocket
s=socket.socket()
s.bind((xxx.xxx.xxx.xxx,xxxx))#ip地址和端标语
s.listen(5)
cs,address=s.accept()
printgotconnectedfrom,address
cs.send(byebye)
ra=cs.recv(512)
printra
cs.close()
客户端:
importsocket
s=socket.socket()
s.connect((xxx.xxx.xxx.xxx,xxxx))#与办事器法式ip地址和端标语雷同
data=s.recv(512)
s.send(hihi)
s.close()
printthedatareceivedis,data
运转:
在本机测试(windows情况下,可以将ip地址改成本机ip,端标语在1024以上,windows将1024以下的为保存),运转--CMD--进入敕令行形式
先python办事器法式,后python客户端法式便可。
或许启动办事器法式后,用telnetip地址端标语,也能够获得异样成果。
让server连续接收衔接
server.py
importsocket
s=socket.socket()
s.bind((192.168.43.137,2000))
s.listen(5)
while1:
cs,address=s.accept()
printgotconnectedfrom,address
cs.send(helloIamserver,welcome)
ra=cs.recv(512)
printra
cs.close()
测试两个一个法式中两个socket并存能否可行
client.py
importsocket
s=socket.socket()
s.connect((192.168.43.137,2000))
data=s.recv(512)
printthedatareceivedis/n,data
s.send(hihiIamclient)
sock2=socket.socket()
sock2.connect((192.168.43.137,2000))
data2=sock2.recv(512)
printthedatareceivedfromserveris/n,data2
sock2.send(clientsendusesock2)
sock2.close()
s.close()
[/code]
如果您觉得本篇CentOSLinux教程讲得好,请记得点击右边漂浮的分享程序,把好文章分享给你的小伙伴们! |
|