端口

在linux系统中,有65536(2的16次方)个端口,分为:

知名端口(Well Known Ports):0-1023,如80端口分配给HTTP服务,21端口分配给FTP服务。

动态端口(Dynamic Ports):1024-65535,一般不固定分配某种服务,而是动态分配。

IP地址

每一个IP地址包括两部分:网络地址和主机地址

A类地址范围:1.0.0.1-126.255.255.254

B类地址范围:128.1.0.1-191.255.255.254

C类地址范围:192.0.1.1-223.255.255.254(常用)

D类地址用于多点广播

E类地址保留,仅作实验和开发用

IP地址127.0.0.1~127.255.255.255用于回路测试

socket

socket(简称套接字) 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的。

套接字使用流程:

  1. 创建套接字
  2. 使用套接字收/发数据
  3. 关闭套接字
import socket

# 创建udp的套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 创建tcp的套接字
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# ...这里是使用套接字的功能(省略)...
# 不用的时候,关闭套接字
udp_socket.close()
tcp_socket.close()

UDP(User Datagram Protocol)

中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议。

创建一个基于udp的网络程序流程很简单,具体步骤如下:

  1. 创建[socket()]客户端套接字
  2. 发送[sendto()]/接收[recvfrom()]数据
  3. 关闭[close()]套接字

UDP发送(客户端):

import socket

# 1. 创建udp套接字
udp_socket = socket(AF_INET, SOCK_DGRAM) # 2. 准备接收方的地址
# '192.168.1.103'表示目的ip地址
# 8080表示目的端口
dest_addr = ('192.168.1.103', 8080) # 注意 是元组,ip是字符串,端口是数字 # 3. 从键盘获取数据
send_data = input("请输入要发送的数据:") # 4. 发送数据到指定的电脑上的指定程序中
udp_socket.sendto(send_data.encode('utf-8'), dest_addr) # 5. 关闭套接字
udp_socket.close()

UDP接收(服务端):

import socket

# 1. 创建udp套接字
udp_socket = socket(AF_INET, SOCK_DGRAM) # 2. 绑定IP和端口
udp_socket.bind('',7788) # 3. 等待接收对方发送的数据
recv_data = udp_socket.recvfrom(1024) # 1024表示本次接收的最大字节数 # 4. 显示对方发送的数据
# 接收到的数据recv_data是一个元组
# 第1个元素是对方发送的数据,需要使用发送时的字符集进行decode解码
# 第2个元素是对方的ip和端口
print(recv_data[0].decode('utf-8'))
print(recv_data[1]) # 5. 关闭套接字
udp_socket.close()

使用socket连接阿里云服务器

客户端在window10本地,服务端在阿里云服务器上,让他们能够通信这里需要注意三点(前提是本地机器能够ping通阿里云服务器的公网IP):

1、服务端绑定的IP地址需要为阿里云服务器的私有IP地址,即ifconfig中的ip,或者绑定时ip地址给空字符串'',这样也会默认绑定私有IP

2、客户端连接的IP地址需要为阿里云服务器的公网IP地址,不能为私有IP。

3、在阿里云控制台的安全组中需要开启相应的协议和端口权限,不然无法连接进阿里云服务器,协议为此次连接的协议,端口为服务器绑定的端口,授权对象为客户端的IP或者0.0.0.0/0表示所有IP都可访问

TCP(Transmission Control Protocol)

中文名是传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。

TCP特点

1. 面向连接

通信双方必须先建立连接才能进行数据的传输,双方都必须为该连接分配必要的系统内核资源,以管理连接的状态和连接上的传输。

双方间的数据传输都可以通过这一个连接进行。

完成数据交换后,双方必须断开此连接,以释放系统资源。

这种连接是一对一的,因此TCP不适用于广播的应用程序,基于广播的应用程序请使用UDP协议。

2. 可靠传输

1)TCP采用发送应答机制

TCP发送的每个报文段都必须得到接收方的应答才认为这个TCP报文段传输成功

2)超时重传

发送端发出一个报文段之后就启动定时器,如果在定时时间内没有收到应答就重新发送这个报文段。

TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。

3)错误校验

TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。

4) 流量控制和阻塞管理

流量控制用来避免主机发送得过快而使接收方来不及完全收下。

TCP与UDP的不同点

  • 面向连接(确认有创建三方交握,连接已创建才作传输。)
  • 有序数据传输
  • 重发丢失的数据包
  • 舍弃重复的数据包
  • 无差错的数据传输
  • 阻塞/流量控制

TCP编程

客户端:

  1. 创建[socket()]客户端套接字
  2. 连接[connect()]服务器
  3. 发送[send()]数据
  4. 接收[recv()]返回的数据
  5. 关闭[close()]套接字
import socket

def main():
# 创建套接字
tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置服务器地址
server_addr = ('xxx.xxx.xxx', 7890) # 阿里云服务器公网IP
# 创建连接
tcp_client.connect(server_addr)
while True:
# 获取发送的数据
send_data = input('请输入发送的数据(exit退出):\n')
if send_data == 'exit':
break
tcp_client.send(send_data.encode('utf-8'))
# 接收服务端返回的数据
recv_data = tcp_client.recv(1024)
print('返回数据为:\n', recv_data.decode('utf-8'))
tcp_client.close() if __name__ == '__main__':
main()

服务端:

  1. 创建[socket()]服务端套接字
  2. 绑定[bind()]IP和端口
  3. 监听[listen()]将套接字变为可以被动链接
  4. 等待[accept()]客户端的连接,返回新的服务套接字服务于该客户端
  5. 新的服务套接字接收[recv()]数据
  6. 给客户端返回[send()]数据
  7. 关闭[close()]新的服务套接字
  8. 关闭[close()]监听的服务套接字
import socket

def client_server(client_socket):
while True:
# 接收数据
recv_data = client_socket.recv(1024)
if not recv_data:
# 关闭服务套接字
client_socket.close()
break
print('接收的数据为:', recv_data.decode('utf-8'))
# 返回数据
client_socket.send('已接收'.encode('utf-8')) def main():
# tcp创建套接字
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定端口
local_addr = ('', 7890)
tcp_server.bind(local_addr)
# 使用listen将其变为被动
tcp_server.listen(128)
while True:
print('准备接收连接.....')
# 等待客户端连接,若有新客户端连接,返回一个新的套接字专门服务这个客户端
client_socket, client_addr = tcp_server.accept()
print('接收到连接,IP:%s PORT:%s' % (client_addr[0], client_addr[1]))
client_server(client_socket) # 关闭监听的套接字
tcp_server.close()
if __name__ == '__main__':
main()

最新文章

  1. GIT的标准文档 使用和服务介绍
  2. 父页面刷新 保持iframe页面url不变
  3. Java 获取到配置文件信息
  4. 基于visual Studio2013解决面试题之0703翻转栈
  5. 出现Data Tools 与VS 不兼容问题
  6. 关于Spring在多线程下的个人疑问
  7. MIP 组件库升级公告
  8. dsp实验一 常见问题教程
  9. 记一个常见的ms sql server中取第N条记录的方法
  10. CSS——Flex
  11. SQL Server 只安装客户端的方法
  12. NCBI通过氨基酸位置查看相邻SNP
  13. 修改select下拉选的默认选中值
  14. elk问题,求教各位大虾!
  15. 教你一招:Microsoft Office Word已停止工作
  16. opencv测试代码
  17. JS封装Cookie
  18. Numeric Type Attributes
  19. 云计算--hbase shell
  20. Mapreduce部署与第三方依赖包管理

热门文章

  1. vue基础入门(2.2)
  2. java中的四种访问权限是?
  3. 【部分】@using (Html.BeginForm())参数示例
  4. MySQL统计库表大小
  5. 【CSGRound1】天下第一 题解
  6. js的几个小问题
  7. SpringBoot启动源码及自定义starter
  8. python实现的udp-收发聊天器
  9. CRC循环冗余校验码
  10. DP没入门就入土