网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API)

主要内容:

  • 1.基于TCP协议下的socket通信流程
  • 2.基于UDP协议下的socket通信流程
  • 3.粘包现象

1.基于TCP协议下的socket通信流程

(1)TCP和UDP的对比

TCP(Transmission Control Protocol)可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;文件传输程序。

UDP(User Datagram Protocol)不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文(数据包),尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)。

应用层
对应协议:HTTP,SMTP,POP3
对应设备:无
传输层
对应协议:TCP与UDP协议
对应设备:四层交换机,四层的路由器
网络层
对应协议:IP协议
对应设备:路由器,三层交换机
数据链路层
对应协议:arp协议
对应设备:网桥,以太网交换机,网卡
物理层
对象协议:无
对应设备:中继器,集线器,双绞线

3次握手

client syn1 随机产生seq=j 进入syn_sent

server 收到syn1 将标志位synACK都置为1 ack=j+1 产生seq=K 进入syn_rcvd状态

client收到后检查ack是不是j+1 如果是将标志位synack都置为1 ack=K+1 双方进established


4次断开

Client发送 fin 进入fin_wait_1状态

Server 收到fin 发送ack 确认序列号+1 close_wait状态  #告诉客户端你先等一下,我看下我的管道里面是否还有信息,如果有给处理完

Server发送一个fin关闭连接  server进入 last_ack状态

Client收到fin进入 time_wait 发送ackserver server进入closed(刻漏声的)

TCP 和UDP下socket差异对比图

(2) TCP协议下的socket通信流程

具体的通信流程

  • 先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。
  • 在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。
  • 客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束

TCP服务器端

import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8898)) #把地址绑定到套接字
sk.listen() #监听链接
conn,addr = sk.accept() #接受客户端链接 执行这句,表示建立了3次握手
ret = conn.recv(1024) #接收客户端信息
print(ret) #打印客户端信息
conn.send(b'hi') #向客户端发送信息
conn.close() #关闭客户端套接字 执行这句,表示经历了4次挥手
sk.close() #关闭服务器套接字(可选) 关闭套接字,不在接收客户端请求。 tcp_server.py

TCP 客户端

import socket
sk = socket.socket() # 创建客户套接字
sk.connect(('127.0.0.1',8898)) # 尝试连接服务器
sk.send(b'hello!')
ret = sk.recv(1024) # 对话(/接收)
print(ret)
sk.close() # 关闭客户套接字 tcp_client.py

#############udp###################

UDP server 通信

import socket
udp_server = socket.socket(type=socket.SOCK_DGRAM) #设置udp方式
ip_port = ('127.0.0.1',8002)
udp_server.bind(ip_port)#把地址绑定到套接字
from_client_msg,client_addr = udp_server.recvfrom(1024)#服务器接收服务发来的值 udp_server.sendto(b'fuwuqi',client_addr)#服务器说 发送给客户端 print(from_client_msg,client_addr)
#打印服务器说的话 客户端的地址

UDP client 通信

import socket
udp_client = socket.socket(type=socket.SOCK_DGRAM)#使用udp方式
ip_port = ('127.0.0.1',8002)##把地址绑定到套接字
udp_client.sendto(b'hello',ip_port)#客户端 向服务器端发动hello ip地址端口 from_server_msg,server_addr = udp_client.recvfrom(1024)#客户端接收服务发来的值
print(from_server_msg,server_addr)#打印出来

################udp  while方式+名字#################

####server
import socket
lst = {'egon': '\033[1;31m', 'yuan': '\033[1;34m'}
sk = socket.socket(type=socket.SOCK_DGRAM)
sk.bind(('127.0.0.1', 9090))
while True:
msg, client_addr = sk.recvfrom(1024) # udp协议不用建立链接
name, mesg = msg.decode('utf-8').split(':')
color = lst.get(name.strip(), '')
print('%s%s\033[0m' % (color, msg.decode('utf-8')))
inp = input('>>>')
sk.sendto(inp.encode('utf-8'), client_addr)
sk.close()

client

import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
name = input('请输入名字: ')
while True:
inp = input('请输入发送内容: ')#名字
sk.sendto(('%s : %s' % (name, inp)).encode('utf-8'), ('127.0.0.1', 9090))
msg, addr = sk.recvfrom(1024)
print(msg.decode('utf-8'))
sk.close()

#################写出面向对象的实现方法

###mysocket.py
from socket import * # 导入socket模块
class Mysocket(socket): # 继承socket
def __init__(self,coding='utf-8'): # 默认编码为utf-8
self.coding = coding
super().__init__(type=SOCK_DGRAM) # 设定为udp协议
def my_recv(self,num): # num表示最大字节,比如1024
msg,addr = self.recvfrom(num)
return msg.decode(self.coding),addr # 返回解码后的接收信息
def my_send(self,msg,addr): # msg和addr分别表示发送信息和连接ip:端口
return self.sendto(msg.encode(self.coding),addr) # 发送编码后的信息
######Server02.py
from mysocket import Mysocket
sk = Mysocket() # 可以指定编码,默认为utf-8
lst = {'eva': '\033[1;31m', 'yuan': '\033[1;34m'}
sk.bind(('127.0.0.1', 9090))
while True:
msg, client_addr = sk.my_recv(1024) # udp协议不用建立链接
name, mesg = msg.split(':')
color = lst.get(name.strip(), '')
print('%s%s\033[0m' % (color, msg))
inp = input('>>>')
sk.my_send(inp, client_addr)
sk.close()
##client02
from mysocket import Mysocket
sk = Mysocket()
name = input('请输入名字: ')
while True:
inp = input('请输入发送内容: ')
sk.my_send(('%s : %s' % (name, inp)), ('127.0.0.1', 9090))
msg, addr = sk.my_recv(1024)
print(msg)
sk.close()

################时间同步服务 

import time
import socket
sk = socket.socket(type = socket.SOCK_DGRAM)
sk.bind(('127.0.0.1',9090))#绑定端口
while True:
msg,addr = sk.recvfrom(1024)#接收
print(msg,addr)
sk.sendto(time.strftime(msg.decode('utf-8')).encode('utf-8'),addr)#发送
sk.close() # a=time.strftime('%Y/%m/%d %H:%M:%S')
# print(a)
import time
import socket sk = socket.socket(type=socket.SOCK_DGRAM)
while True:
sk.sendto('%Y/%m/%d %H:%M:%S'.encode('utf-8'), ('127.0.0.1', 9090)) # 执行时间格式
ret, addr = sk.recvfrom(1024)#接收
print(addr,ret.decode('utf-8'))
time.sleep(1) # 暂停1秒执行
sk.close()

python socket原理 及socket如何使(tcp udp协议)的更多相关文章

  1. 网络编程—网络基础概览、socket,TCP/UDP协议

    网络基础概览 socket概览 socket模块—TCP/UDP的实现 TCP/UDP总结 网络基础概览 osi七层协议各层主要的协议 # 物理层传输电信号1010101010 # 数据链路层,以太网 ...

  2. QQ--基于TCP/UDP协议的通讯原理

    QQ是一个基于TCP/UDP协议的通讯软件  发送消息的时候是UDP打洞,登陆的时候使用HTTP~因为登陆服务器其实就是一个HTTP服 务器,只不过不是常用的那些,那个服务器是腾讯自行开发的!   一 ...

  3. TCP/UDP协议(二)

    面试问题:Tcp/Udp协议是什么,各有什么异同点,各自的使用场景? Tcp协议(传输控制协议) tcp是面向连接的协议,在收发数据之前,必须与对方建立可靠的连接: 三次握手:简单形象通俗描述: 主机 ...

  4. java 通过TCP\UDP 协议实现多人聊天,点对点,文件传送-----分服务器端和客户端

    java 通过TCP\UDP 协议实现多人聊天,点对点,文件传送-----分服务器端和客户端 启动界面如下图: 首先启动服务器: 客户端登陆,登陆成功后为: 默认发送是全部用户,是多人发送. 当在边列 ...

  5. TODO:Golang语言TCP/UDP协议重用地址端口

    TODO:Golang语言TCP/UDP协议重用地址端口 这是一个简单的包来解决重用地址的问题. go net包(据我所知)不允许设置套接字选项. 这在尝试进行TCP NAT时尤其成问题,其需要在同一 ...

  6. TCP/UDP协议简要梳理

    TCP/UDP协议简要梳理 TCP TCP,Transmission Control Protocol,传输控制协议是一种面向连接的.可靠的.基于字节流的传输层通信协议.在因特网协议族中,TCP所在的 ...

  7. Shell 脚本实现TCP/UDP协议通讯

    Shell 脚本实现TCP/UDP协议通讯 http://www.cnblogs.com/occult/archive/2012/12/25/2832183.html  

  8. TCP/UDP协议、理解三次握手四次挥手、Socket

    一.什么是socket? 中文名叫套接字,是对底层的 TCP IP UDP 等网络协议进行封装,使得上层的应用程序开发者,不用直接接触这对复杂,丑陋的协议. 在程序员的言论,他就是一个封装好的模块,要 ...

  9. tcp / udp 协议及其实现的socket

    一.tcp协议 1.1 基本知识 特点: 可靠,慢,全双工通信 建立连接时:三次握手 断开连接时:四次挥手 在建立起连接之后 发送的每一条信息都有回执 为了保证数据的完整性,还有重传机制 长连接:会一 ...

随机推荐

  1. OneinStack——PHP多版本共存

    前言 我事先安装的是LNMP环境,PHP版本为7.2,但是现在环境需要一个PHP5.6,所以就准备安装个上版本,顺带写个安装教程,写完后我发现了原来有直接安装的命令!所以后面的内容大家可以忽略了!从配 ...

  2. Sublime Text3 如何开启Debug

    打开setting-user 首选项——>Package Settings——>Package Control——>settings-user 添加"debug" ...

  3. ☆ [HDU2157] How many ways?? 「矩阵乘法求路径方案数」

    传送门:>Here< 题意:给出一张有向图,问从点A到点B恰好经过k个点(包括终点)的路径方案数 解题思路 一道矩阵乘法的好题!妙哉~ 话说把矩阵乘法放在图上好神奇,那么跟矩阵唯一有关的就 ...

  4. 基于FPGA的16阶级联型iir带通滤波器实现

    警告 此文章将耗费你成吨的流量,请wifi下阅读,造成的流量浪费本人不承担任何责任.初版源代码获取(请勿用作他用,仅供学习):https://gitee.com/kingstacker/iir.git ...

  5. centos6.8下安装破解quartus prime16.0以及modelsim ae安装

    前言 装逼使用 流程 安装modelsim: 1.modelsim ae在linux下是32位的,对于64位系统需要安装32位库:yum install xulrunner.i686 2.给予权限: ...

  6. Ionic的页面堆栈与Tabs菜单相遇的问题(页面堆栈有多个)

    本来的需求: 新建的Ionic项目是Tabs菜单,假设有两个选项卡 A 和 B(从左到右),对应的两个页面的代码完全一样,使用了echarts 插件,并且使用了一个获取页面元素的方法,给自己的一个变量 ...

  7. Markdown 使用技巧

    懒得复制,直接贴网页吧 懒得复制,直接贴网页吧*2 懒得复制,直接贴网页吧*3

  8. 【AtCoder3611】Tree MST(点分治,最小生成树)

    [AtCoder3611]Tree MST(点分治,最小生成树) 题面 AtCoder 洛谷 给定一棵\(n\)个节点的树,现有有一张完全图,两点\(x,y\)之间的边长为\(w[x]+w[y]+di ...

  9. python服务器文件上传下载+GUI【tkinter】

    大概就是一个通过应用程序来和服务器打交道的这么一个,小东西 1.GUI 用的是tkinter # -*- coding: UTF-8 -*- from tkinter import * import ...

  10. 【原创】tyvj1038 忠诚 & 计蒜客 管家的忠诚 & 线段树(单点更新,区间查询)

    最简单的线段树之一,中文题目,不翻译.... 注释讲的比较少,这已经是最简单的线段树,如果看不懂真的说明最基础的理论没明白 推荐一篇文章http://www.cnblogs.com/liwenchi/ ...