socket是什么

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

所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。

也有人将socket说成ip+port,ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的一个应用程序,ip地址是配置到网卡上的,而port是应用程序开启的,ip与port的绑定就标识了互联网中独一无二的一个应用程序

而程序的pid是同一台机器上不同进程或者线程的标识

套接字分类:

  基于文件类型的套接字家族

套接字家族的名字:AF_UNIX

  基于网络类型的套接字家族

套接字家族的名字:AF_INET

六 套接字工作流程

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

 socket()模块函数用法

import socket
socket.socket(socket_family,socket_type,protocal=0)
socket_family 可以是 AF_UNIX 或 AF_INET。socket_type 可以是 SOCK_STREAM 或 SOCK_DGRAM。protocol 一般不填,默认值为 0。 获取tcp/ip套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 获取udp/ip套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 由于 socket 模块中有太多的属性。我们在这里破例使用了'from module import *'语句。使用 'from socket import *',我们就把 socket 模块里的所有属性都带到我们的命名空间里了,这样能 大幅减短我们的代码。
例如tcpSock = socket(AF_INET, SOCK_STREAM

实例: 基于TCP协议

服务端

import socket

# 创建socket对象  指定type参数为socket.SOCK_DGRAM 表示使用UDP协议
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # datagram数据报的意思
# 绑定ip和端口
server.bind(("127.0.0.1",8888)) while True:
# 接收数据 返回一个元祖 数据和 发送方的地址
msg,c_addr = server.recvfrom(1024)
print("收到来自%s: 说:%s" % (c_addr[0] ,msg.decode("utf-8")))
# 发送数据到指定ip和端口
server.sendto(msg.upper(),c_addr)
客户端

import socket

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # datagram数据报的意思

while True:
msg = input(">>>:")
client.sendto(msg.encode("utf-8"),("127.0.0.1",8888))
data,addr = client.recvfrom(1024)
print(data.decode("utf-8"))

下面是 采用打电话的场景描述:

#服务器
# import socket
# #买电话
# phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# #插卡
# phone.bind(('127.0.0.1',12012)) #端口范围0-65535 0-1024 给系统用的
# #开机
# phone.listen(5) # 5 表示同一时间 最大接受请求值为5
# #等电话
# conn,client_addr = phone.accept()
# print('接受到',client_addr,'的电话')
# #收信息
# msg = conn.recv(1024) # 1024是一个最大值 限制
# print(msg.decode('utf-8'))
# #回信息
# conn.send('然后呢'.encode('utf-8'))
# #挂电话
# conn.close()
# #关机
# phone.close()
#客户端

# import socket
# # #买电话
# # phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# # #拨号
# # phone.connect(('127.0.0.1',12012))
# # #发信息
# # phone.send('哈哈哈哈哈哈哈哈'.encode('utf-8'))
# # #收信息
# # data = phone.recv(1024)
# # print(data.decode('utf-8'))
# # #挂电话
# # phone.close()

先运行服务器,在运行客户端,不然会:

Traceback (most recent call last):
File "F:/练习/客户端.py", line 18, in <module>
phone.connect(('127.0.0.1',2323))
ConnectionRefusedError: [WinError 10061] 由于目标计算机积极拒绝,无法连接。

tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端

tcp服务端

服务端套接字函数
s.bind()    绑定(主机,端口号)到套接字   接受一个元组参数
s.listen()  开始TCP监听
s.accept()  被动接受TCP客户的连接,(阻塞式)等待连接的到来

客户端套接字函数
s.connect()     主动初始化TCP服务器连接
s.connect_ex()  connect()函数的扩展版本,出错时返回出错码,而不是抛出异常

公共用途的套接字函数
s.recv()            接收TCP数据
s.send()            发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)
s.sendall()         发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)
s.recvfrom()        接收UDP数据
s.sendto()          发送UDP数据
s.getpeername()     连接到当前套接字的远端的地址
s.getsockname()     当前套接字的地址
s.getsockopt()      返回指定套接字的参数
s.setsockopt()      设置指定套接字的参数
s.close()           关闭套接字

面向锁的套接字方法
s.setblocking()     设置套接字的阻塞与非阻塞模式
s.settimeout()      设置阻塞套接字操作的超时时间
s.gettimeout()      得到阻塞套接字操作的超时时间

面向文件的套接字的函数
s.fileno()          套接字的文件描述符
s.makefile()        创建一个与该套接字相关的文件

TCP服务端:

import socket
# 使用TCP 可以直接默认
server = socket.socket() # 指定端口 和 ip 端口 - 1023是系统保留的
server.bind(("127.0.0.1",)) # 监听请求 参数为最大半连接数(三次握手未完成的请求 可能是服务器来不及 客户端恶意攻击)
server.listen()
# 为了可以不断的接受客户端连接请求
while True:
# 接受连接请求
c,addr = server.accept()
# 为了可以重复收发数据
while True:
try:
# 程序的最大缓冲区容量 返回值类型为bytes类型
data = c.recv().decode("utf-8")
# 如果客户端断开连接(客户端调用了close) recv 返回值为kong 此时应该结束循环
if not data:# 在linux中 客户端异常关闭 服务器也会收空
print("client closed!")
c.close()
break
#解码
print(data)
# 回复数据 将原始数据转为大写
c.send(data.upper().encode("utf-8"))
except ConnectionResetError:
print("客户端异常关闭!!")
c.close()
break
# 关闭资源
server.close() # TCP断开连接的正确姿势
# 客户端调用close
# 服务器判断如果接收数据为空则相应的调用close

服务端

基于网络编程 TCP协议 及 socket 基本语法的更多相关文章

  1. 网络编程——TCP协议、UDP协议、socket套接字、粘包问题以及解决方法

    网络编程--TCP协议.UDP协议.socket套接字.粘包问题以及解决方法 TCP协议(流式协议) ​ 当应用程序想通过TCP协议实现远程通信时,彼此之间必须先建立双向通信通道,基于该双向通道实现数 ...

  2. 网络编程TCP协议-聊天室

    网络编程TCP协议-聊天室(客户端与服务端的交互); <span style="font-size:18px;">1.客户端发数据到服务端.</span> ...

  3. 网络编程 TCP协议:三次握手,四次回收,反馈机制 socket套接字通信 粘包问题与解决方法

    TCP协议:传输协议,基于端口工作 三次握手,四次挥手 TCP协议建立双向通道. 三次握手, 建连接: 1:客户端向服务端发送建立连接的请求 2:服务端返回收到请求的信息给客户端,并且发送往客户端建立 ...

  4. python 网络编程 -- Tcp协议

    Socket是网络编程的一个抽象概念.通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可. 客户端 大多数连接都是可靠 ...

  5. 网络编程——TCP协议的三次握手和四次挥手

    三次握手原理解析 TCP握手协议在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND ...

  6. 网络编程——TCP协议和通信

    第1章 TCP通信 TCP通信同UDP通信一样,都能实现两台计算机之间的通信,通信的两端都需要创建socket对象. 区别在于,UDP中只有发送端和接收端,不区分客户端与服务器端,计算机之间可以任意地 ...

  7. java 网络编程 TCP协议 java 服务器和客户端 java socket编程

    一个 HelloWord 级别的 Java Socket 通信的例子.通讯过程:        先启动 Server 端,进入一个死循环以便一直监听某端口是否有连接请求.然后运行 Client 端,客 ...

  8. 网络编程——TCP协议

    1.TCP程序概述 TCP是一个可靠的协议,面向连接的协议. 实现TCP程序,需要编写服务器和客户端,Java API为我们提供了java.net包,为实现网络应用程序提供类. ServerSocke ...

  9. [Python 网络编程] TCP、简单socket模拟ssh (一)

    OSI七层模型(Open System Interconnection,开放式系统互联) 应用层 网络进程访问应用层: 为应用程序进程(例如:电子邮件.文件传输和终端仿真)提供网络服务: 提供用户身份 ...

随机推荐

  1. vue项目打包问题

    使用vue-cli脚手架构建vue项目 vue init webpack project npm run build 打包时出现 Tip: built files are meant to be se ...

  2. java的instanceof关键字

    java 中的instanceof 运算符是用来判断对象是否是 特定类或这个特定类的子类 的一个实例. 用法: result = object instanceof class 参数: Result: ...

  3. Yii1.1框架实现PHP极光推送消息通知

    一.下载极光推送PHP SDK,解压后放在/protected/components/目录下,如下图所示: 二.完善修改下官方的demo例子,我这里复制一份demo,改为NotifyPush.php, ...

  4. Day13 Python基础之time/datetime/random模块一(十一)

    time模块 import time print(help(time)) time.time() #return current time in seconds since the Epoch as ...

  5. PS 十分钟教你做出文字穿插效果

  6. 使用队列queue实现一个简单的生产者消费者模型

    一.生产者消费者模型 我们去超市商店等地购买商品时,我们大部分人都会说自己是消费者,而超市的各大供货商.工厂等,自然而然地也就成了我们的生产者.如此一来,生产者有了,消费者也有了,那么将二者联系起来的 ...

  7. 生成短链接的URL

    假设你想做一个像微博短链接那样的短链接服务,短链接服务生成的URL都非常短例如: http://t.cn/E70Piib, 我们应该都能想到链接中的E70Piib对应的就是存储长链接地址的数据记录的I ...

  8. docker技术之基本命令

    我们使用基本命令之前,先来普及一下操作中使用的基本概念 镜像   image 容器   container 仓库   repository 镜像 Docker 镜像是一个特殊的文件系统,除了提供容器运 ...

  9. js this的含义以及讲解

    this关键字是一个非常重要的语法点.毫不夸张地说,不理解它的含义,大部分开发任务都无法完成. 首先,this总是返回一个对象,简单说,就是返回属性或方法“当前”所在的对象. 下面来两个例子来让大家更 ...

  10. 解决.Net Mvc跨域请求问题

    针对ASP.NET MVC和ASP.NET Web API两种项目类型 1.针对ASP.NET MVC,只需要在web.config中添加如下的内容即可 <system.webServer> ...