网络编程socket之一
从今年10月22号开始我的python学习之路,一个月下来,磕磕碰碰,勉勉强强把基础部分算是学完了,一个月走过来,我过着别人看似单调,重复的生活,确实是,每天,每周都是一样的生活模式,早上7点40起床,吃个早餐,8点到达教室,中午1点去吃个午饭,然后回到教室,下午6点去吃个晚饭,然后回到教室,待到晚上11点回家洗个澡睡觉,每天都一样的。我的朋友会问我,这样的生活不无聊吗?我回答是不,我的朋友可能认为两年的军旅生活早就让我习惯了单调无味的生活,我觉得有可能两年军旅生活确实让我有强大的适应性,但我认为最主要的是我真心觉得学习编程语言让我很感兴趣,以前的我感觉网络啊,计算机等这类东西感觉好遥远,根本无法触及,但现在我能去控制它,是多么牛逼的事。前一个月基础部分不算很难,只要逻辑思维跟上,就基本不是问题,而且涛哥真的讲的很好,很有耐心,很感谢涛哥。从这周三开始接触网络编程,一上来就很懵逼,什么ip啊,MAC地址啊,交换机啊,路由器等等关于计算机和网络的东西真的让我很萌,根本不知道是啥,相当于重新认知新事物,但几天学习下来,感觉这类东西是要学习的,但对于现阶段的我来说,不用太深入去专研,而主要是的是学会网络编程过程,接下来,我就把这几天所学到知识跟大家分享一下。
一,名词解释
路由器:电脑上所有与公网之间的消息的传递的进出口都在路由器上,路由器有公网IP,这个IP是全球网络连接的唯一标识,路由器具有消息转发的功能
交换机:主要是把连接到交换机上的电脑连接到一起,其次是交换机还可以设定一个IP范围,从而使得广播的范围缩小
IP:IP分为两个,一个是电脑上由交换机分配的IP,这个IP在一个子网内是不可以重复的;另一个是公网IP,是路由器上的,这个是全球网络连接间的唯一标识
MAC地址:电脑上的网卡在出厂时被烧制上的全球唯一标识码
DHCP协议:这是交换机上动态分配电脑IP的协议
ARP协议:这是交换机上的IP和MAC对应表,我们可以通过IP来查找出对应的MAC地址
DNS服务器:这是域名解析器,我们可以通过输入域名来查找对应的公网IP
网关:这相当于路由器上看门的,也就是 路由器上的公网IP,在公网上传输的数据,只有在目标IP和网关一致时,网关才会让数据进来
子网掩码:主要用于判断两个IP是否属于一个子网
二,网络通信流程
上图为网络通信流程图,主要分为以下三种情况:(以下三种情况描述纯属个人行为,不正确之处请指正)
一、从1号电脑传输数据到2号电脑
首先1号电脑把数据发到交换机A,数据主要包括2号电脑IP,自身电脑IP和MAC地址,加上真正要传的内容,数据到交换机A后,经过ARP协议,加上2号电脑的IP获得对应的MAC地址,交换机A就会在自身所连接的子网内广播,在这子网内的电脑都会收到信息,在2号电脑收到消息后,确认是自己IP和MAC地址,然后就确认接收数据,其他的电脑确认不是自身的IP和MAC,就直接扔掉,这样就完成了 数据传输。
二、从1号电脑传输数据到3号电脑
首先1号电脑把数据发到交换机A,数据主要包括3号电脑IP,自身电脑IP和MAC地址,加上真正要传的内容,数据到交换机A后,交换机A就会在自身所连接的子网内广播,但没找到,于是把数据抛给路由器,然后由路由器广播到接入此路由器的交换机,找到对应的交换机2,通过交换机2广播,找到3号电脑,完成通信。
三,从1号电脑到4号服务器
首先在1号电脑上浏览器上输入4号服务器上一个网的域名,通过DNS服务器查找域名对应的公网IP,然后把请求一层层发到路由器,路由器经过计算最有路径,找到目标公网IP对应的路由,然后根据公网IP和程序端口号找到要访问的网页,然后服务器在刚才的路径返回回去,把网页内容返回给1号电脑,此时我们就完成了通信,就可以上网了。
三,两种架构
C/S架构:即client客户端/server服务端架构,比如qq,微信,客户端需要下载应用程序,安装之后才可以使用
B/S架构:即browser浏览器端和server服务器端,比如各种网页啊,这个是不需要下载安装应用程序
四、osi七层模型
五,TCP协议和UDP协议区别
tcp协议:可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;文件传输程序
udp协议:不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文(数据包),尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)
在tcp协议下,是基于连接的,为了保证数据安全,存在一个三次握手,四次挥手的过程,而udp协议无连接的,所以没有这过程。
三次握手:
- TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;
- TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
- TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。
- TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。
- 当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。
四次挥手:
数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,然后客户端主动关闭,服务器被动关闭。服务端也可以主动关闭,一个流程。
- 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
- 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
- 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
- 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
- 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
- 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
六、套接字socket
套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。 因此,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。
七、基于tcp下的socket
在tcp下,基于连接的,需要先启动服务端,在启动客户端。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束
服务端程序
import socket #引入模块
server=socket.socket() #创建server对象
ip_port=('192.168.15.78',8888) #声明服务端的IP和程序端口
server.bind(ip_port) #把ip_port绑定到对象
server.listen() #监听
while 1:
conn,addr=server.accept() #等待客户端连接
while 1:
server_msg=input('服务端:')
conn.send(server_msg.encode('utf-8')) #向客户端发送消息
from_client_msg=conn.recv(1024) #接收客户端消息
print(from_client_msg.decode('utf-8'))
if from_client_msg.decode('utf-8')=='byebye': #如果收到消息为byebye,就断开此次连接,继续等待下一个客户端连接
break #这就是优雅的断开
conn.close()
server.close()
客户端程序
import socket
client=socket.socket()
server_ip_port=('192.168.15.78',8888) #设置要连接服务端程序的IP和端口
client.connect(server_ip_port) #进行连接
while 1:
from_server_msg=client.recv(1024) #接收服务端消息
print(from_server_msg.decode('utf-8'))
client_msg=input('客服端:')
client.send(client_msg.encode('utf-8')) #向服务端发送消息
if client_msg=='byebye': #如果输入为byebye,就断开连接
break
client.close()
tcp属于长连接,长连接就是一直占用着这个链接,这个连接的端口被占用了,第二个客户端过来连接的时候,他是可以连接的,但是处于一个占线的状态,就只能等着去跟服务端建立连接,除非一个客户端断开了(优雅的断开可以,如果是强制断开就会报错,因为服务端的程序还在第一个循环里面),然后就可以进行和服务端的通信了
八、基于udp协议下的socket
基于udp协议下的socket是不需要连接的。服务器端先初始化Socket,然后与端口绑定(bind),recvform接收消息,这个消息有两项,消息内容和对方客户端的地址,然后回复消息时也要带着你收到的这个客户端的地址,发送回去,最后关闭连接,一次交互结束
服务端
import socket
server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server_ip_port=('192.168.12.39',8888)
server.bind(server_ip_port) while 1:
from_client_msg, adrr = server.recvfrom(1024)
print('来自%s的消息:%s'%(adrr,from_client_msg.decode('utf-8')))
if from_client_msg.decode('utf-8')=='bye':
break
msg=input('请输入:')
msg1=msg+','+from_client_msg.decode('utf-8').replace('sb','alexsb')
server.sendto(msg1.encode('utf-8'),adrr)
客户端
import socket
client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server_ip_port=('192.168.12.39',8888)
while 1:
msg=input('请输入:')
client.sendto(msg.encode('utf-8'),server_ip_port)
if msg=='bye':
break
from_server_msg,adrr=client.recvfrom(1024)
print(from_server_msg.decode('utf-8'))
client.close()
网络编程socket之一的更多相关文章
- 网络编程socket基本API详解(转)
网络编程socket基本API详解 socket socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信. socket ...
- Android 网络编程 Socket
1.服务端开发 创建一个Java程序 public class MyServer { // 定义保存所有的Socket,与客户端建立连接得到一个Socket public static List< ...
- 网络编程Socket之TCP之close/shutdown具体解释(续)
接着上一篇网络编程Socket之TCP之close/shutdown具体解释 如今我们看看对于不同情况的close的返回情况和可能遇到的一些问题: 1.默认操作的close 说明:我们已经知道writ ...
- 铁乐学Python_Day33_网络编程Socket模块1
铁乐学Python_Day33_网络编程Socket模块1 部份内容摘自授课老师的博客http://www.cnblogs.com/Eva-J/ 理解socket Socket是应用层与TCP/IP协 ...
- Python网络编程socket
网络编程之socket 看到本篇文章的题目是不是很疑惑,what is this?,不要着急,但是记住一说网络编程,你就想socket,socket是实现网络编程的工具,那么什么是socket,什么是 ...
- java网络编程socket\server\TCP笔记(转)
java网络编程socket\server\TCP笔记(转) 2012-12-14 08:30:04| 分类: Socket | 标签:java |举报|字号 订阅 1 TCP的开销 a ...
- linux网络编程-socket(37)
在编程的时候需要加上对应pthread开头的头文件,gcc编译的时候需要加了-lpthread选项 第三个参数是线程的入口参数,函数的参数是void*,返回值是void*,第四个参数传递给线程函数的参 ...
- python网络编程-socket编程
一.服务端和客户端 BS架构 (腾讯通软件:server+client) CS架构 (web网站) C/S架构与socket的关系: 我们学习socket就是为了完成C/S架构的开发 二.OSI七层 ...
- Python开发【第八篇】:网络编程 Socket
Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...
- python网络编程socket /socketserver
提起网络编程,不同于web编程,它主要是C/S架构,也就是服务器.客户端结构的.对于初学者而言,最需要理解的不是网络的概念,而是python对于网络编程都提供了些什么模块和功能.不同于计算机发展的初级 ...
随机推荐
- s5 Docker的持久化存储和数据共享
数据库容器的数据如何才能不会丢失?Docker的持久化存储技术.Docker的数据共享技术能极大提高开发人员的开发效率,边写代码,边看运行结果. 数据持久化之Data Volume Docker持久化 ...
- EventTrigger动态添加监听事件
在 Unity3D 中,通过拖拽的方式在 EventTrigger 组件中添加监听事件就不多说了,很简单.这里主要说的是通过代码动态往 EventTrigger 组件中添加监听事件,有个很坑的地方,就 ...
- eclipse怎么删除多余的tomcat server(2)
首先你的Server要是可用状态,就是说当前这个tomcat处于可用状态才能点击那个Create Launch Configuration
- js实现抽奖
抽奖.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- Django URLConf 进阶
Django处理一个请求 项目启动后根据 settings ROOT_URLCONF 决定项目根URLconf urlpatterns是django.conf.urls.url()实例的一个Pyth ...
- cobub razor 安装及使用
server端安装及配置 apache2 + Mysql5.7 + php7 + redis 参见:http://docs.cobub.com/pages/viewpage.action?pageId ...
- PMS构造函数以及apk如何扫描
一.PackageManagerService构造函数 1.创建data目录下面以及文件(settings的构造函数),然后再添加6个SharedUserSetting 2.开始扫描并且解析APK 3 ...
- 使用FFmpeg如何转发一个RTSP视频流
版权声明:转载请说明出处:http://www.cnblogs.com/renhui/p/6930221.html 转发RTSP流,这类需求一般出现于转发一些摄像头采集视频,并在摄像头上做RTSP ...
- Tools - Atom编辑器
Atom官网 Atom编辑器的常用插件 预览 document-outline:Show a heirarchical outline of a text document minimap:A pre ...
- vueAdmin ui基础包
这个版本的vueAdmin ui是针对官网版本进行修改而成,主要修改了后端接口修改,登录等等,一个通用的前端工程基础包,即开即用,省去了前期繁琐配置 Demo Build Setup # Clone ...