zl程序教程

您现在的位置是:首页 >  后端

当前栏目

python网络编程学习笔记(二):socket建立网络客户端

2023-06-13 09:15:27 时间

1、建立socket

建立socket对象需要搞清通信类型和协议家族。通信类型指明了用什么协议来传输数据。协议的例子包括IPv4、IPv6、IPX\SPX、AFP。对于internet通信,通信类型基本上都是AF_INET(和IPv4对应)。协议家族一般表示TCP通信的SOCK_STREAM或者表示UDP通信的SOCK_DGRAM。因此对于TCP通信,建立一个socket连接的语句为:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
对于UDP通信,建立一个socket连接的语句为:
s=socket.socket(socket.AF_INET,SOCK_DGRAM)

2、连接socket

连接socket需要提供一个tuple,包括host(主机名或者IP)和port(远程端口),类似代码为:
s.connect(("www.baidu.com",80)

3、寻找端口号

socket库中利用getservbyname()函数可以查询端口号,一般需要两个参数:一是协议名,如http、smtp、pop3等,一个是端口名,如tcp、udp

例如:

importsocket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
port=socket.getservbyname("http","tcp")
port的返回值为80。若改为:
port=socket.getservbyname("smtp","tcp")
port的返回值为25。

4、从socket获取信息

建立socket连接后,可以通过getsockname()获取本身的ip地址和端口号,也可以通过getpeername()显示远程机器的ip地址和端口号。
如:在pythonshell中

>>>importsocket
>>>s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
>>>port=socket.getservbyname("http","tcp")
>>>s.connect(("www.baidu.com",port))
>>>prints.getsockname()
("192.168.87.138",3213)
>>>prints.getpeername()
("220.181.111.147",80)

Socket模块的类方法
类方法说明
Socket低层网络接口(每个BSDAPI)
socket.socket(family,type)创建并返回一个新的socket对象
socket.getfqdn(name)将使用点号分隔的IP地址字符串转换成一个完整的域名
socket.gethostbyname(hostname)将主机名解析为一个使用点号分隔的IP地址字符串
socket.fromfd(fd,family,type)从现有的文件描述符创建一个socket对象

Socket模块的实例方法

实例方法说明
sock.bind((adrs,port))将socket绑定到一个地址和端口上
sock.accept()返回一个客户机socket(带有客户机端的地址信息)
sock.listen(backlog)将socket设置成监听模式,能够监听backlog外来的连接请求
sock.connect((adrs,port))将socket连接到定义的主机和端口上
sock.recv(buflen[,flags])从socket中接收数据,最多buflen个字符
sock.recvfrom(buflen[,flags])从socket中接收数据,最多buflen个字符,同时返回数据来源的远程主机和端口号
sock.send(data[,flags])通过socket发送数据
sock.sendto(data[,flags],addr)通过socket发送数据
sock.close()关闭socket
sock.getsockopt(lvl,optname)获得指定socket选项的值
sock.setsockopt(lvl,optname,val)设置指定socket选项的值

举例:
>>>importsocket
>>>socket.gethostbyname("www.baidu.com")
"220.181.111.147"
>>>socket.gethostbyname("www.126.com")
"123.125.50.22"
>>>socket.getfqdn("123.125.50.22")
"123.125.50.22"
这里getfqdn却不能返回域名?

5、处理错误
关于错误异常的处理,主要就是用try、except语句。如将python网络编程学习笔记(1)中gopherclient.py进行一下修改:

复制代码代码如下:


#-*-coding:cp936-*-
##modifyby小五义
importsocket,sys
port=70
host=sys.argv[1]

filename=sys.argv[2]

try:
   s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
exceptSocket.error,e:
   print"建立socket错误:%s"%e

try:
   s.connect((host,port))
exceptsocket.gaierror,e:
   print"host或者端口错误:%s"%e
exceptsocket.error,e:
   print"连接错误:%s"%e

try:
   s.sendall(filename+"\r\n")
exceptsocket.error,e:
   print"数据发送错误:%s"%e
   sys.exit(1)


while1:
   try:
       buf=s.recv(2048)
   exceptsocket.error,e:
       print"接收错误:%s"%e
       sys.exit(1)
   if"doesnotexist"inbuf:
       print"%s文件不存在"%filename
   else:
       ifnotlen(buf):
           break
       sys.stdout.write(buf)

运行结果是:

C:\>pythongopherclient.pyquux.org/wh.txt
连接错误:[Errno10060]
数据发送错误:[Errno10057]由于套接字没有连接并且(当
据报套接字时)

C:\>pythongopherclient.pyquux.orgwh.txt
wh.txt文件不存在

=======================================================================================================================
对python网络编程学习笔记(1)的添加
笔记1中在dos下运行pythongopherclient.pyquux.org系统提示出错的问题,终于明白了。错误原因是少了文件名。如在quux.org/有whatsnew.txt,于是在dos下运行pythongopherclient.pyquux.orgwhatsnew.txt。这时会将whatsnew.txt的内容全部列出。