python学习day30 网络基础 TCP协议 osi模型 套接字(socket)模块

ttp://www.cnblogs.com/Eva-J/articles/8066842.html

 一些概念

不同机器上的程序之间通信

所有的网络通信都基于客户端与服务端

服务端:要一直运行,等待服务别人

客户端:客户用的时候才使用的服务

 

 想要实现通信:

网卡网线

网卡上有全球唯一的mac地址 由12位16进制数表示 前六位是厂商编号,后六位是流水线号

ip地址:0.0.0.0 - 255.255.255.255  十进制 八进制中网络部分是前24位,主机部分是后8位

127.0.0.1是自己的回环地址

现在最广泛的最主要还是IPv4,v6又增加了两个字节

ip地址通过arp协议就能找到对应的mac地址

交换机的出现解决了多台机器的通信问题

arp协议:

 

广域网与路由器

 

网关

局域网中的机器想要访问局域网外的机器需要通过网关访问

IP地址 与 子网掩码 按位与

比如我的IP地址:10.41.157.29   二进制:00001010.00101001.10011101.00011101

子网掩码:255.255.0.0  二进制:11111111.11111111.00000000.00000000

按位进行与运算 :00001010.00101001.00000000.00000000  这是局域网的网段地址  10.41.0.0   前三字节是局域网的网段,最后一个字节可变

 

通过网络找到机器后,怎么能找到要通信的程序呢?

端口 port

在计算机上,每个需要网络通信的程序,都会开一个端口。同一时间只会有一个程序占用一个端口,不可能在同一时间有两个端口占用

端口范围:0-65535   一般情况下 开8000之后的端口

ip+端口  就可以在茫茫的网络中,找到唯一的机器上的唯一上的程序

 

TCP协议和UDP协议

当应用程序希望通过 TCP 与另一个应用程序通信时,它会发送一个通信请求。这个请求必须被送到一个确切的地址。在双方“握手”之后,TCP 将在两个应用程序之间建立一个全双工 (full-duplex) 的通信。全双工:双方都可以收发信息

这个全双工的通信将占用两个计算机之间的通信线路,直到它被一方或双方关闭为止。

建立链接:三次握手  一般都是客户端发起

断链:四次挥手

只要连上了,就会一直占用着,知道断开

UDP

不占连接 收没收到不一定

QQ就是基于UDP的协议

 

TCP可看成打电话,UDP看成发短信  写信

TCP是面向连接的,有比较高的可靠性, 一些要求比较高的服务一般使用这个协议,如FTP、Telnet、SMTP、HTTP、POP3等。
而UDP是面向无连接的,使用这个协议的常见服务有DNS、SNMP、QQ等。对于QQ必须另外说明一下,QQ2003以前是只使用UDP协议的,其服务器使用8000端口,侦听是否有信息传来,客户端使用4000端口,向外发送信息(这也就不难理解在一般的显IP的QQ版本中显示好友的IP地址信息中端口常为4000或其后续端口的原因了),即QQ程序既接受服务又提供服务,在以后的QQ版本中也支持使用TCP协议了。

 

互联网协议与osi模型

传输过程:

数据链路层跟arp协议打交道的

 应用层的协议: http(https)网页协议,ftp文件传输协议,SMTP邮件相关的协议

Socket概念

主机的IP地址加上主机上的端口号作为连接的端点,这种端点就叫做套接字(socket)或插口。
套接字用(IP地址:端口号)表示。
用于描述IP地址和端口,是一个通信链的句柄。

套接字(Socket)是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

可以看成一个模块

 

套接字家族

从Socket角度看TCP和UDP协议:

基于TCP协议的socket

 server端

import socket

sk = socket.socket()
# bind中传入一个元组 元组中是ip地址和端口 端口是整数
sk.bind(('127.0.0.1',8898))  #把地址绑定到套接字
sk.listen()          #监听链接 等着别人的请求

conn,addr = sk.accept() #接受客户端链接 conn 连接  addr 别人的地址

ret = conn.recv(1024)  #接收客户端信息 默认传入1024
print(ret)       #打印客户端信息
conn.send(b'hi')        #向客户端发送信息

conn.close()       #关闭客户端套接字

sk.close()        #关闭服务器套接字(可选) 如果不关闭,还能继续接收

client端

import socket

sk = socket.socket()           # 创建客户套接字
sk.connect(('127.0.0.1',8898))    # 尝试连接服务器

sk.send(b'hello!')
ret = sk.recv(1024)         # 对话(发送/接收)
print(ret)

sk.close()            # 关闭客户套接字

例子: 聊天

有收必有发,收发必平等。send和recv必相等

客户端:

import socket

sk = socket.socket()

sk.connect(('127.0.0.1', 8080))

while True:
    info = input('>>>')
    sk.send(bytes(info.encode('utf-8')))
    ret = sk.recv(1024).decode('utf-8')
    print(ret)
    if ret == 'bye':
        sk.send(b'bye')
        break

sk.close()

注意:

# 以下两者是一样的
bytes('你好', encoding='utf-8')
bytes('你好'.encode('utf-8'))

 

服务端:

import socket
sk = socket.socket()
sk.bind(('127.0.0.1', 8080))
sk.listen()

conn, addr = sk.accept()
print(addr)
while True:
    ret = conn.recv(1024).decode('utf-8')
    if ret == 'bye':
        break
    print(ret)
    info = input('>>>')
    conn.send(bytes(info, encoding='utf-8'))

conn.close()
sk.close()

 

 

posted @ 2019-01-03 12:32  xyfun72  阅读(223)  评论(0编辑  收藏  举报