转载请注明:@小五义
小五义 - 博客园www.cnblogs.com/xiaowuyi服务器和客户端程序很类似,上节学习了客户端程序,这一节将仔细学习一下利用socket建立TCP服务器和UDP服务器。
1、TCP连接的建立方法
客户端在建立一个TCP连接时一般需要两步,而服务器的这个过程需要四步,具体见下面的比较。
下面具体来讲这四步的建立方法:
第一步,建立socket对象:这里与客户端一样,依然是:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
第二步,设置和得到socket选项
python定义了setsockopt()和getsockopt(),一个是设置选项,一个是得到设置。这里主要使用setsockopt(),具体结构如下:
setsockopt(level,optname,value)
level定义了哪个选项将被使用。通常情况下是SOL_SOCKET,意思是正在使用的socket选项。它还可以通过设置一个特殊协议号码来设置协议选项,然而对于一个给定的操作系统,大多数协议选项都是明确的,所以为了简便,它们很少用于为移动设备设计的应用程序。
optname参数提供使用的特殊选项。关于可用选项的设置,会因为操作系统的不同而有少许不同。如果level选定了SOL_SOCKET,那么一些常用的选项见下表:
本节在学习时,用到了SO_REUSEADDR选项,具体写法是:
S.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 这里value设置为1,表示将SO_REUSEADDR标记为TRUE,操作系统会在服务器socket被关闭或服务器进程终止后马上释放该服务器的端口,否则操作系统会保留几分钟该端口。
下面的方法可以帮助给出该系统下python所支持的socket选项列表:
import socket solist=[x for x in dir(socket) if x.startswith(SO_)] solist.sort() for x in solist: Print x第三步:绑定socket
绑定即为服务器要求一个端口号。
S.bind((host,port)),其中host为服务器ip,通常为空,也可以绑定到一个特定的ip地址。Port为端口号。
第四步:侦听连接。
利用listen()函数进行侦听连接。该函数只有一个参数,其指明了在服务器实际处理连接的时候,允许有多少个未决(等待)的连接在队列中等待。作为一个约定,很多人设置为5。如:s.listen(5)
2、简单的TCP服务器实例
这个建立一个简单的TCP服务器和客户端。
服务器端:TCP响应服务器,当与客户端建立连接后,服务器显示客户端ip和端口,同时将接收的客户端信息和I get it!传给客户端,此时等待输入一个新的信息传给客户端。
客户端:TCP客户端,首先输入服务器ip地址,然后输入信息,回车后会得到服务器返回信息,然后等待服务器向其发送信息后退出。
具体代码如下:
服务器端:tcpserver.py
# -*- coding: cp936 -*- import socket,traceback host= port=12345 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) while 1: try: clientsock,clientaddr=s.accept() except KeyboardInterrupt: raise except: traceback.print_exc() continue try: print "连接来自:",clientsock.getpeername() while 1: data=clientsock.recv(4096) if not len(data): break print clientsock.getpeername()[0]+:+str(data) clientsock.sendall(data) clientsock.sendall("\nI get it!\n") t=raw_input(input the word:) clientsock.sendall(t) except (KeyboardInterrupt,SystemExit): raise except: traceback.print_exc() try: clientsock.close() except KeyboardInterrupt: raise except: traceback.print_exc()客户端:tcpclient.py
# -*- coding: cp936 -*- import socket,sys port=12345 host=raw_input(输入服务器ip:) data=raw_input(输入要发送的信息:) s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) try: s.connect((host,port)) except: print 连接错误! s.send(data) s.shutdown(1) print 发送完成。 while 1: buf=s.recv(4096) if not len(buf): break sys.stdout.write(buf)执行结果:
客户端输入hello,服务器端输入ok,具体显示结果是:
服务器端:
连接来自:(127.0.0.1,1945)
127.0.0.1:hello
Input the world:ok
客户端:
输入服务器ip:127.0.0.1
输入要发送的信息:hello
发送完成。
hello
I get it!
ok
3、UDP服务器
UDP服务器建立与TCP相类似,具体比较如下:
这里利用UDP建立一个时间服务器。
代码如下:
服务器端;serverudp.py
# -*- coding: cp936 -*- import socket,traceback,time,struct host= port=12345 s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) s.bind((host,port)) while 1: try: message,address=s.recvfrom(8192) secs=int(time.time()) reply=struct.pack("!I",secs) s.sendto(reply,address) except (KeyboardInterrupt,SystemExit): raise except: traceback.print_exc()客户端:clientudp.py
# -*- coding: cp936 -*- import socket,sys,struct,time host=raw_input(输入服务器地址:) port=12345 s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) s.sendto(,(host,port)) print "等待回复……" buf=s.recvfrom(2048)[0] if len(buf)!=4: print "回复错误%d:%s"%(len(buf),buf) sys.exit(1) secs=struct.unpack("!I",buf)[0] print time.ctime(int(secs))运行结果:
首先运行服务器端,然后运行客户端。
C:\>python clientudp.py##clientudp.py程序存放在在c盘下
输入服务器地址:127.0.0.1
等待回复……