美文网首页
网络编程基础(一)

网络编程基础(一)

作者: ikaroskun | 来源:发表于2017-03-12 18:28 被阅读190次

网络编程基础(一)

一、套接字

1.分类
1.1面向连接的套接字

面向连接的套接字,需要在通信之前就要先建立一个连接,也称为虚拟电路或者流套接字。

实现这种连接类型的主要协议为`传输控制协议TCP`,创建`TCP`套接字必须要使用`SOCK_STREAM`作为套接字类型。

1.2面向无连接的套接字

在通信开始之前不需要进行建立连接,也被称为数据报。

这种连接类型的主要协议为`用户数据报服务UDP`, 创建这种套接字,必须要使用`SOCK_DGRAM`作为套接字类型.

二、基本使用

1.socket模块函数

创建socket的一般语法:

socket(socket_family, socket_type, protocol=0)

eg: TCP
tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
eg: UDP
usp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

如果我们使用from socket import *导入socket属性,即将socket属性引入命名空间中,那么就可以使用下面的简短代码创建套接字:

tcp_sock = socket(AF_INET, SOCK_STREAM)

2.常见的套接字对象方法:

名称 描述
服务器套接字方法
s.bind() 将地址(主机名,端口号对)绑定到套接字上
s.listen() 设置并启动TCP监听器
s.accept() 被动接受TCP客户端的连接,一直等待知道连接到达(阻塞)
客户端套接字方法
s.connect() 主动发起TCP服务器连接
s.connect_ex() connect()的扩展版本,此时会以错误码形式返回问题,而不是抛出异常普通的套接字方法
s.recv() 接收TCP消息
s.recv_into() 接收TCP消息到指定的缓冲区
s.send 发送TCP消息
s.sendall() 完整的发送TCP消息
s.recvfrom() 接收UDP消息
s.recvfrom_into() 接收UDP消息到指定的缓冲区
s.sendto() 发送UDP消息
s.getpeername() 连接到套接字(TCP)的远程地址
s.getsockname() 当前套接字的地址
s.getsockopt() 返回给定套接字选项的值
s.setsockopt() 设置给定套接字选项的值
s.shutdown() 关闭连接
s.close() 关闭套接字
s.detach() 在未关闭文件描述符的情况下关闭套接字,返回文件描述符
s.ioctl() 控制套接字的模式(仅仅支持windows系统)
s.functl() 控制套接字的模式(对于POSIX系统)
面向阻塞的套接字方法
s.setblocking() 设置套接字的阻塞或者非阻塞模式
s.settimeout() 设置阻塞套接字的操作的超时时间
s.gettimeout() 获取阻塞套接字操作的超时时间
面向文件的套接字方法
s.fileno() 套接字的文件描述符
s.makefile() 创建于套接字关联的文件对象
数据属性
s.family() 套接字家族
s.tyep() 套接字类型
s.proto() 套接字协议

三、创建服务器和客户端

(一).TCP的Server和Client

1.TCP server

伪代码模版块:
ss = socket()               # 创建服务器套接字
ss.bind()                   # 套接字与地址绑定 
ss.listen()                 # 监听连接
inf_loop:                   # 服务器无限循环
    cs = ss.accept()        # 接收客户端连接
    comm_loop():            # 通信循环
        cs.recv()/cs.send() # 对话(接收/发送)
    cs.close()              # 关闭客户端套接字
ss.close()                  # 关闭服务器套接字 (可选)

简述:

1、所有的套接字通过使用socket.socket()函数来创建的。
2、由于服务器需要占用一个端口并等待客户端的请求,所以其必须绑定 到一个本地地址,TCP是面向连接的,在其开始操作之前,必须安装一些基本设施。
3、监听连接后,服务器就可以开始他的无线循环
4、调用accept()之后,开启了(单线程)服务器,等待连接。默认下,accept()是阻塞的。
5、服务器接收连接之后,就会返回(利用accept())一个独立的客户端套接字,用来进行数据交换。
客户端关闭连接之后,不会影响服务端的无线循环。但可以使用close()函数主动退出。

Demo:

# 一个TCP-server,
# 接收客户端的信息,并打上时间戳,返回给client
# 返回格式: time + data
# 
# coding=utf-8

from socket import *
from time import ctime

# 相关属性
host = ''   # 变量是空白的,对bind()函数的标识,其可以使用任何可用地址。
port = 21567
buffer_size = 1024
address = (host, port)

# 建立连接
tcp_server = socket(AF_INET, SOCK_STREAM)
tcp_server.bind(address)
tcp_server.listen(5)   # 同时连接的最大值

# 逻辑
while True:
    print ("[+] waiting for connection...")
    tcp_client, address = tcp_server.accept()  # 得到连接客户端的套接字
    print ("[+] ...connected from:", address)

    while True:
        data = tcp_client.recv(buffer_size)  # 得到客户端发送的数据
        if not data:
            break
        tcp_client.send('[M] [%s] %s' % (ctime(), data))  # 返回已处理数据

    tcp_client.close()
tcp_server.close()   # 这一行永远不会执行

2.TCP Client

# 伪代码板块

cs = socket()              # 创建客户端套接字
cs.connect()               # 尝试连接服务器
comm_loop:                 # 通信循环
    cs.send()/cs.recv()    # 对话(发送/接收)
cs.close()                 # 关闭客户端套接字

简述:

1、利用socket.socket()创建的
2、利用Connect连接到服务器

Demo:

# coding=utf-8

from socket import *

# 属性
host = 'localhost'
port = 21567
buffer_size = 1024
address = (host, port)

# 连接
tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(address)

# 逻辑处理
while True:
    data = raw_input('>> ')
    if not data:
        break
    tcp_client.send(data)
    data = tcp_client.recv(buffer_size)
    if not data:
        break
    print data

tcp_client.close()

(二).UDP的Server和Client

1. UDP server

# 伪代码板块

ss.socket()           # 创建服务器套接字
ss.bind()             # 绑定服务器套接字
inf_loop:             # 服务器无限循环
    cs = ss.recvfrom()/ss.sendto()  # 接收/发送
ss.close()            # 关闭服务器套接字

简述:

1、对于UDP的连接,不需要很多设置,在这里,它与TCP服务器最显著的差别: 没有为了确认成功通信而使客户端连接到一个独立的套接字

Demo:

# coding=utf-8

from socket import *
from time import ctime

# 属性
host = ''      # 变量是空白的,对bind()函数的标识,其可以使用任何可用地址。
port = 21567
buffer_size = 1024
address = (host, port)

udp_server = socket(AF_INET, SOCK_DGRAM)
udp_server.bind(address)

while True:
    print ("[+] waiting for connection...")
    data, address = udp_server.recvfrom(buffer_size)
    udp_server.sendto("[M] [%S] %s " % (ctime(), data), address)
    print "[+] ...received from and returned to:", address

udp_server.close()

2.udp client

# 伪代码
cs = socket()    # 创建客户端套接字
comm_loop:       # 通信循环
    cs.sendto()/cs.recvfrom    # 对话(发送/接收)
cs.close()       # 关闭客户端套接字

简述:

对于UDP连接,一旦创建了套接字对象,就进入对话循环中通信结束时,就会关闭套接字

Demo:

# coding=utf-8

from socket import *

# 属性
host = 'localhost'
port = 21567
buffer_size = 1024
address = (host, port)

# 连接
udp_client = socket(AF_INET, SOCK_DGRAM)

while True:
    data = raw_input(">> ")
    if not data:
        break
    udp_client.sendto(data, address)
    data, address = udp_client.recvfrom(buffer_size)
    if not data:
        break
    print data

udp_client.close()

四、有关socket模块的属性介绍

在下面给出一些socket常见的属性:

属性名称 描述
数据属性
AF_UNIX、AF_INET、AF_INET6、AF_NETLINK、AF_TIPC python中所支持的套接字地址家族
SO_STREAM、SO_DGRAM 套接字类型(TCP-流、UDP-数据报)
has_ipv6 指示是否支持IPV6的布尔标记
异常
error 套接字的相关错误
herror 主机和地址相关错误
gaierror 地址相关错误
timeout 超时时间
函数
socket() 以给定的地址家族、套接字类型和协议类型(可选)创建一个套接字对象
socketpair() 以给定的地址家族、套接字类型和协议类型(可选)创建一对套接字对象
create_connection() 常规函数,它接收一个地址(主机号、端口)对,返回套接字对象
fromfd() 以一个打开的文件描述符创建一个套接字对象
ssl() 通过套接字启动一个安全套接字层连接,不执行证书认证
getaddrinfo() 获得一个五元组序列形式的地址信息
getnameinfo() 给定一个套接字地址,返回(主机号、端口号)二元组
getfqdn() 返回完整的域名
gethostname() 返回当前主机名
gethostbyname() 将一个主机名映射到它的IP地址
gethostbyname_ex() gethostbyname()的扩展版本,它返回主机名、别名主机集合和IP地址列表
gethostbyaddr() 将一个IP地址映射到DNS信息;返回与gethostbyname_ex()相同的三元组
getserverbyname()/getserverbyport() 将一个服务名映射到一个端口,或者反过来;对于任何一个函数来说,协议名都是可选的。
ntohl()/ntohs() 将来自网络的整数转换为主机字节顺序
htonl()/htons() 将来自主机的整数转换为网络字节顺序
inet_aton()/inet_ntoa() 将IP地址八进制字符串转换为32位的包格式,或者反过来;仅使用与IPV4地址
inet_pton()/inet_ntop() 将IP地址字符串转换为打包的二进制格式,或者反过来。(同时适用IPV4、IPV6)
getdefaulttimeout() 以秒(浮点数)为单位返回默认套接字超时时间
setdefaulttimeout() 以秒(浮点数)为单位设置默认套接字超时时间

以上就是对于网络编程基础的介绍,接下来,会以实现一个类QQ的通信进行练习。(见二)

相关文章

  • iOS之网络基础(网络请求)

    一.网络基础 1 网络基础 001网络编程 (1)网络编程是一种实时更新应用数据的常用手段 ...

  • iOS-网络基础及应用-Http

    3.网络基础 3.1 网络基础 001 问题:为什么要学习网络编程? 回答:(1)网络编程是一种实时更...

  • Android应用开发:网络编程2

    网络编程 Java基础:网络编程 Uri、URL、UriMatcher、ContentUris详解 Android...

  • Http协议

    网络编程 Java基础:网络编程 Uri、URL、UriMatcher、ContentUris详解 Android...

  • 网络编程基础(一)

    1 什么是Socket? Socket是进程通讯的一种方式,即调用这个网络库的一些API函数实现分布在不同主机的相...

  • 网络编程基础(一)

    网络编程基础(一) 一、套接字 1.分类1.1面向连接的套接字 1.2面向无连接的套接字 二、基本使用 1.soc...

  • 网络基本了解

    网络基础 问题:为什么要学习网络编程?(1)网络编程是一种实时更新应用数据的常用手段(2)网络编程是开发优秀网络应...

  • I/O模型学习小记

    基础概念 通过I/O模型学习同步/异步、阻塞/非阻塞基础概念,参考资料如下:《Unix网络编程》《网络编程释疑之:...

  • Python爬虫 - 网络编程

    1. 网络编程基础 1.1 介绍 网络编程基础(1) OSI模型和TCP/IP协议计算机网络、OSI七层模型、TC...

  • 网络编程基础

    网络七层协议 应用层: 用户接口,应用层序,网关,HTTP协议等 表示层:数据表示,相当于一个东西的表示,比如图片...

网友评论

      本文标题:网络编程基础(一)

      本文链接:https://www.haomeiwen.com/subject/xgeogttx.html