补一篇3年前的学习笔记
文章目录
- 1、原理简述
- 1.1、通信
- 1.2、通信协议
- 1.3、网络协议
- 1.4、套接字
- 2、socket
- 2.1、牛郎织女版
- 2.1.1、服务端
- 2.1.2、客户端
- 2.2、海王版
- 2.2.1、服务端
- 2.2.2、客户端
- 3、补充一个Java版的socket
1、原理简述
1.1、通信
- 通信:通过第三方(信号)进行信息的转达
发送者 ---第三方(信号)---> 接收者
1.2、通信协议
- 通信协议:双方实体完成通信或服务所必须遵循的规则和约定
底层协议:控制硬件 发收信号
高层协议:对信息和数据进行编码和解码协议的实现
早期协议:直接由硬件决定
现代协议:硬件+协议程序网络协议 常见类型协议间转换
1.3、网络协议
网络协议计算机网络中进行数据交换而建立的规则、标准或约定的集合TCP/IP协议(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)能在多个不同网络间实现信息传输的协议簇
1.4、套接字
对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。
一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。
2、socket
2.1、牛郎织女版
2.1.1、服务端
from socket import socket
# 1. 创建【TCP流式 套接字对象】
sock_stream = socket()
# 2. 将【套接字对象】与【本机IP地址+端口号】绑定在一起
sock_stream.bind(('127.0.0.1', 8888))
# 3. 将套接字变为【可监听的套接字】并设置一个连接等待队列
sock_stream.listen()
print('等待连接...\n', sock_stream)
# 4. 套接字等待客户端请求
conn, addr = sock_stream.accept()
print('创建一个新的套接字,与客户端的ip地址对应\n', conn)
print('连接到客户端的IP地址是', addr)
# 5. 收消息
data = conn.recv(1024)
print('接收到的数据', data.decode()) # .decode() 解码
# 6. 发消息
n = conn.send(b'receive\n')
print('发送了的字节数', n)
# 7. 和客户端断开连接
conn.close()
# 8. 清除套接字
sock_stream.close()
2.1.2、客户端
from socket import socket
# 1. 创建客户端套接字(要和访问的服务器的套接字类型相同)
s = socket()
# 2. 连接服务器
s.connect(('127.0.0.1', 8888))
# 3. 发消息
s.send(b'i am client')
# 4. 收消息
data = s.recv(1024)
print('客户端收到的信息:', data)
# 5. 关闭套接字
s.close()
2.2、海王版
2.2.1、服务端
from socket import socket
from threading import Thread
def target(conn, addr):
"""处理客户端的函数"""
print('连接\033[93m{}\033[0m'.format(addr))
while True:
data = conn.recv(1024).decode().strip()
if not data:
break
conn.send(data.encode())
print('{}的消息\033[035m{}\033[0m'.format(addr, data))
print('断开\033[93m{}\033[0m'.format(addr))
conn.close()
# 创建套接字, 绑定, 监听
stream = socket()
stream.bind(('127.0.0.1', 8888))
stream.listen()
# 多线程接收客户端的连接请求
while True:
Thread(target=target, args=stream.accept()).start()
2.2.2、客户端
from socket import socket
# 创建客户端套接字(要和访问的服务器的套接字类型相同)并连接服务器
s = socket()
s.connect(('127.0.0.1', 8888))
# 发、收 消息
while s.send(input('发消息:').strip().encode()):
print('收信息:\033[93m{}\033[0m'.format(s.recv(1024).decode()))
# 关闭套接字
s.close()
3、补充一个Java版的socket
TCP服务端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args) throws IOException {
// 1、创建服务端对象,设定端口号
ServerSocket serverSocket = new ServerSocket(6666);
// 2、接收客户端请求
Socket socket = serverSocket.accept();
// 3、获取输入流数据
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int i;
while ((i = inputStream.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, i));
}
// 4、服务器给客户端发消息
OutputStream outputStream = socket.getOutputStream();
outputStream.write("receive".getBytes());
socket.shutdownOutput(); // 通知客户端写完了
// 5、关闭资源
outputStream.close();
inputStream.close();
socket.close();
serverSocket.close();
}
}
TCP客户端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class TCPClient {
public static void main(String[] args) throws IOException {
// 1、创建客户端对象
String host = "127.0.0.1"; // 服务器地址:本机
int port = 6666; // 服务器端口号(1024~49151)
Socket socket = new Socket(host, port);
// 2、向服务端发数据
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello".getBytes());
// 3、通知服务器写完了(不写这句的话,服务器会等)
socket.shutdownOutput();
// 4、接收服务器
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int i;
while ((i = inputStream.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, i));
}
// 5、关闭资源
inputStream.close();
outputStream.close();
socket.close();
}
}