python网络编程基础socket模块

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/comprel/article/details/72824784

python 网络编程 socket

socket网络套接字,提供基础的网络编程服务
SocketServer 提供较高级的服务,简化网络编程

socket提供如下方法:

异常:

1.exception socket.error
套接字相关的错误,返回(errno, string),或者一个字符串。socket.error 是IOError错误的一种

2.exception socket.herror
调用gethostbyname_ex(), gethostbyaddr() 抛出的主机与地址错误 ,返回(h_errno, string) ,string是c函数hstrerror()返回
3.exception socket.gaierror
地址相关的错误,一般是调用getaddrinfo(),getnameinfo()时。返回(error, string),string是错误的具体描述,是由c函数gai_strerror()返回。
error的值是定义为EAI_* 中的一个值
4.exception socket.timeout 超时

python支持的套接字地址家族:

socket.AF_UNIX
socket.AF_INET
socket.AF_INET6

套接字类型:

socket.SOCK_STREAM
socket.SOCK_DGRAM
socket.SOCK_RAW
socket.SOCK_RDM
socket.SOCK_SEQPACKET

比较常用的是:socket.SOCK_STREAM ,socket.SOCK_DGRAM

函数对象

1.socket.create_connection(address[, timeout[, source_address]])
建立tcp连接,地址(host, port),返回一个socket对象,比socket.connect()高级
如果host是非数字的ip地址,则会使用AF_INET and AF_INET6进行地址解析
timeout超时,若没有指定,则设置为默认,默认值可以使用getdefaulttimeout()
source_address源端地址(host, port) 如果host或者port是”或0,则使用默认的

2.socket.getaddrinfo(host, port[, family[, socktype[, proto[, flags]]]])
获取地址信息返回(family, socktype, proto, canonname, sockaddr)5元组
例如:

>>> import socket
>>> socket.getaddrinfo("example.org", 80, 0, 0, socket.IPPROTO_TCP)
[(2, 1, 6, '', ('93.184.216.34', 80)), (10, 1, 6, '', ('2606:2800:220:1:248:1893:25c8:1946', 80, 0, 0))]
>>> 

3.socket.getfqdn([name])
获取完整域名

4.socket.gethostbyname(hostname)
dns解析,主机名解析为ip

5.socket.gethostbyname_ex(hostname)
gethostbyname的扩展,返回主机名,ip,别名

6.socket.gethostname()
返回主机名gethostbyname(gethostname()).可以获得当前主机的ip

7.socket.gethostbyaddr(ip_address)
返回(hostname, aliaslist, ipaddrlist),获取一个ip的dns信息

8.socket.getnameinfo(sockaddr, flags)
给定ip返回(host, port)

9.socket.getprotobyname(protocolname)
协议映射到数字

10.socket.getservbyname(servicename[, protocolname])
将服务映射到端口 protocolname可以是tcp或udp,其他的都是全匹配

11.socket.getservbyport(port[, protocolname])
根据端口获取服务名

12.socket.getdefaulttimeout()
获取默认超时

13.socket.setdefaulttimeout(timeout)
设置默认超时

14.socket.socketpair([family[, type[, proto]]])
用给定地址家族建立连接

15.socket.fromfd(fd, family, type[, proto])
用一个打开的文件描述符创建套接字对象

16.主机字节序与网络字节序转换,详情参看手册
socket.ntohl(x)
socket.ntohs(x)
socket.htonl(x)
socket.htons(x)

17.socket.socket([family[, type[, proto]]])

socket对象

socket对象提供如下方法:
服务器端套接字
socket.bind(address) 绑定套接字, 在AF_INET下,以元组(host,port)的形式表示地址。
socket.listen() 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,一般设置为5即可。
socket.accept() 被动接受TCP客户端连接,(阻塞式)等待连接的到来,返回(conn, address)
客户端套接字
socket.connect(address) 服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
socket.connect_ex(address) connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
公共用途的套接字函数
socket.recv() 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
socket.send() 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。
socket.sendall() 完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
socket.recvfrom() 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
socket.sendto() 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。
socket.close() 关闭套接字,它会释放连接资源,如果要及时关闭连接,则可以在close()之前使用shutdown()
socket.getpeername() 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
socket.getsockname() 返回套接字自己的地址。通常是一个元组(ipaddr,port)
socket.setsockopt(level,optname,value) 设置给定套接字选项的值。
socket.getsockopt(level,optname[.buflen]) 返回套接字选项的值。
socket.settimeout(timeout) 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect())
socket.gettimeout() 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。
socket.fileno() 返回套接字的文件描述符。
socket.setblocking(flag) 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。
socket.makefile() 创建一个与该套接字相关连的文件
socket.shutdown(how) how可以是:SHUT_WR不再发送 SHUT_RDWR不再发送和接收

如下模型:

服务端:

import socket

HOST = '' 
PORT = 50007 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
    data = conn.recv(1024)
    if not data: break
    conn.sendall(data)
conn.close()

客服端:

import socket

HOST = 'localhost'    # The remote host
PORT = 50007              # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)

输出:
服务端:
Connected by (‘127.0.0.1’, 43991)
客服端:
Received ‘Hello, world’

示例:
服务端:

#coding=utf8
import socket              

s = socket.socket()        
host = socket.gethostname()
port = 12345               
s.bind((host, port))       

s.listen(5)                
while True:
    c, addr = s.accept()  
    print 'get from :', addr
    c.send('hello,welcome')
    c.close() 

客户端:

#coding=utf8
import socket  

s = socket.socket()
host = socket.gethostname()
port = 12345

s.connect((host, port))
print s.recv(1024)
s.close()  

输出:

客服端:

[root@myrpc t]# python cc.py 
hello,welcome
[root@myrpc t]# python cc.py 
hello,welcome
[root@myrpc t]# python cc.py 
hello,welcome
[root@myrpc t]# python cc.py 
hello,welcome
[root@myrpc t]# python cc.py 
hello,welcome

服务端:

get from : ('192.168.137.19', 48552)
get from : ('192.168.137.19', 48553)
get from : ('192.168.137.19', 48554)
get from : ('192.168.137.19', 48555)
get from : ('192.168.137.19', 48556)

端口扫描:

import socket 
import threading 
from Queue import Queue 

def scan(port): 
  s = socket.socket() 
  s.settimeout(1) 
  if s.connect_ex(('localhost', port)) == 0: 
     print "local open port : %d"%port
  s.close() 

def worker(): 
  while not q.empty(): 
    port = q.get() 
    try: 
      scan(port) 
    finally: 
      q.task_done() 

if __name__ == '__main__': 
  q = Queue() 
  map(q.put,xrange(1,65535)) 
  threads = [threading.Thread(target=worker) for i in xrange(100)] 
  map(lambda x:x.start(),threads) 
  q.join() 

猜你喜欢

转载自blog.csdn.net/comprel/article/details/72824784