您的位置:首页 > 理论基础 > 计算机网络

Python 基础 网络编程基础

2019-01-19 17:06 363 查看

一   引入

我们可以在我们的电脑上和别人聊天,可以在自己的电脑上向网盘中上传、下载内容。这些都是两个程序在通信。由于在不同机器上的程序需要通信,才产生了网络。

二   网络编程

就是通过网络让不同计算机上运行的程序可以进行通信。

例如两台电脑上的qq通过网络进行相互聊天。

三   软件开发架构

两个程序之间通讯的应用大致可以分为两种:

第一种是应用类程序:qq、微信、网盘、优酷这一类是属于需要安装的桌面应用

第二种是web类程序:用户只需要浏览器即可访问程序。常见的web类应用程序

比如百度、知乎、CSDN等使用浏览器访问就可以直接使用。

不管是应用类程序还是web类程序,这些应用的本质其实都是两个程序之间的通讯。

而这两个分类又对应了两个软件开发的架构~

1  客户端服务端概念

客户端:就是我们常用的程序例如qq,微信,浏览器等等

服务端:要一直运行着给别人提供服务的机器(电脑,服务器)

2  C/S  架构

C/S  即:Client与Server ,中文意思:客户端与服务器架构

这里的客户端一般泛指客户端应用程序exe,程序需要先安装后,才能在电脑上运行,对用户的操作系统环境依赖较大

3 B/S  架构 

B/S即:Browser与Server,中文意思:浏览器端与服务器端架构。

只需在浏览器上通过HTTP去请求服务器端相关的资源(网页资源)。

四   计算机网络

1   TCP  协议

TCP(Transmission Control Protocol)可靠的、面向连接的协议

(什么是面向连接呢?就是发送消息之前先建立连接然后再发送消息例如打电话场景,在网络中具体指的是三次握手)

TCP协议特点:数据安全,速度略低。分为客户端和服务端。

使用TCP的应用:Web浏览器;电子邮件等程序。

TCP的三次握手和4次挥手

TCP三次握手:

三次握手就是客户端和服务器进行通信的时候有三次交流。例如如下:

客户端问服务端你准备好了吗(第一次),服务端告诉客户端装备好了,并且问客户端你准备好了吗(第二次),客户端说我准备好了(第三次)。

第一次握手:是客户端让服务器准备好资源。

第二次握手:服务端资源准备好了并且服务端问客户端资源有没有准备好。

第三次握手:客户端资源也准备好了。接下来才真正的发生数据。

真正进行3次握手的时候发送的是值。

第一次客户端装备了一个值例如是11,发送给了服务端,服务端如果准备好了就将11+1变成12再发送给客户端,表示服务端准备好了资源。

服务怎么知道客户端准备好了资源呢?服务器给客户端发送一次数据例如33,客户端如果准备好了就再将数据加1 33+1 =34 发送给服务端,服务端接受到后就表明客户端准备好了。这样4次才知道双方准备好了资源。这里发生了4次,不是3次。

 

四次挥手:

建立一个连接需要三次握手,而终止一个连接要经过四次挥手。

(1) 某个应用进程首先调用close,称该端执行“主动关闭”(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。

(2) 接收到这个FIN的对端执行 “被动关闭”(passive close),这个FIN由TCP确认。

注意:FIN的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候该应用进程接收的任何其他数据之后,因为,FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。

(3) 一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致 4000 它的TCP也发送一个FIN。

(4) 接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。

 

2  UDP 协议

UDP协议:面向无连接,数据不安全,速度快。不区分客户端与服务端。

用于网络电话,在线视频网络会议等等,要求实时性比较高(数据传输快)不能有延迟。

当应用程序希望通过UDP与一个应用程序通信时,传输数据之前源端和终端不建立连接。

当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。

因此UDP是不可靠无连接的协议。因为有可能数据会丢失。

 

3  TCP 和 UDP  的对比

TCP--提供的是面向连接、可靠的服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。

UDP--是一个简单的不可靠的运输层协议。它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快

4 OSI模型

OSI模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系,一般称为OSI参考模型或七层模型

OSI模型又将TCP/IP协议族的四层进行了具体划分,划分成了7层。

每次运行常见的协议

五   Socket概念

1.理解Socket

首先我们写的网络编程,属于应用层,当我们写好了程序后,需要将数据发送给运输层,

但是应用层和运输层通信需要遵循相关协议,关键是我们不了解运输层的协议,那该怎么办呢?因此提供了Socket层,Socket英文插座,插口,套接字意思。

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,让Socket去组织数据,以符合指定的协议。(面向对象的特点,我们只负责编写逻辑即可,不用去管TCP/IP具体的格式,Sockect会帮我们做)。

2  Socket 发展史

套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。

3

(1)基于文件型

套接字家族的名字:AF_UNIX

unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信

(2)基于网络型

套接字家族的名字:AF_INET

(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)

(3)Socket 参数详解

 

family 地址系列应为AF_INET(默认值),AF_INET6,AF_UNIX,AF_CAN或AF_RDS。
(AF_UNIX 域实际上是使用本地 socket 文件来通信   
type 套接字类型应为SOCK_STREAM(默认值),SOCK_DGRAM,SOCK_RAW或其他SOCK_常量之一。
SOCK_STREAM 是基于TCP的,有保障的(即能保证数据正确传送到对方)面向连接的SOCKET,多用于资料传送。 
SOCK_DGRAM 是基于UDP的,无保障的面向消息的socket,多用于在网络上发广播信息

 

(4)基于TCP协议的Socket使用

[code]#服务端
import socket
#买手机
server_sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)     #创建套接字
#插卡
server_sk.bind(('127.0.0.1',9998))   #绑定IP地址和端口号   当ip设置为 '0.0.0.0' 时   默认为关闭防火墙
#开机
server_sk.listen(128)    #默认并发量
#等待
print('1111111')
new_socket,addr = server_sk.accept() #等待客户端的连接
print(addr)
# ret  返回值是个元组(socket,addr)  第一个参数是一个新的socket,负责和客户端收发数据,
# 第二个数据是客户端的地址和端口
print('22222')
# 通话
ret = new_socket.recv(1024)#接受客户端发送过来的数据    b  字节
print(ret.decode())
#挂电话
new_socket.close()
#关机

客户端
import socket
client_ck = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#和服务端进行三次连接
client_ck.connect(('127.0.0.1',9998))

client_ck.send('你好  世界   ---9998---'.encode('utf-8'))

client_ck.close()
[code]服务端
import socket

server_sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ip_port = ('127.0.0.1',9998)
server_sk.bind(ip_port)
server_sk.listen(128)
new_socket,addr = server_sk.accept()

while True:
ret = new_socket.recv(1024).decode('utf-8')
print(ret)
if ret == 'bay':
break
content = input('服务端::')
new_socket.send(content.encode('utf-8'))
if content == 'bay':
break
new_socket.close()
server_sk.close()

客户端
import socket

client_sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ip_port = ('127.0.0.1',9998)
client_sk.connect(ip_port)
# 给服务端发消息
while True:
ret = input('客户端>>')
client_sk.send(ret.encode('utf-8'))
if ret == 'bay':
break
#接受服务器发送过来的消息
content = client_sk.recv(1024).decode('utf-8')
if content == 'bay':
break
else:
print(content)

client_sk.close()

(5)基于UDP协议的Socket的使用

[code]服务端:
import socket
#1创建socket
sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#2 绑定端口
sk.bind(('127.0.0.1',9998))
print('1111')
#3 接受内容
content,addr = sk.recvfrom(1024)
print(content.decode('utf-8'))
#4关闭
sk.close()

客户端:
import socket
#1创建socket
sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

#发送内容
sk.sendto('hello'.encode(),('127.0.0.1',9999))

sk.close()

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: