1、网络编程基础
其他
2020-03-04 00:51:31
阅读次数: 0
1. socket之send和recv的原理剖析
- 当创建一个Tcp Socket对象时,会有一个发送缓冲区与一个接收缓冲区,这个发送缓冲区与接收缓冲区指的是内存中的一片空间。
- send原理:应用程序把发送的数据先写入到发送缓冲区,再由操作系统控制网卡把发送缓冲区的数据发送给服务端网卡。
- recv原理:应用程序调用操作系统接口,由操作系统通过网卡接收数据,把接收的数据写入到接收缓冲区,应用程序再从接收缓冲区获取客户端发送的数据。
2. 端口和端口号
- 端口号有65536个。
- 应用程序通过ip地址找到设备,通过端口号找到对应的端口,然后通过端口把数据传输给应用程序。
- 端口号可以标识唯一的一个端口。
- 端口号的分类
- 知名端口号(众所周知的端口号,范围:0~1023)
- 动态端口号(开发应用程序使用的端口号,范围:1024~65535)
3. tcp
- tcp是一个稳定、可靠的传输协议,常用于对数据进行准确无误的传输。
- 特点:面向连接、可靠传输
4. socket
- 作用:负责进程之间的网络数据传输。
5. tcp网络应用程序的开发流程
- 客户端开发流程
- 服务端开发流程
6. tcp客户端程序示例
- 示例
import socket
if __name__ == '__main__':
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_client_socket.connect("192.168.132.128", 8080)
send_content = "hello"
send_data = send_content.encode("utf-8")
tcp_client_socket.send(send_data)
recv_data = tcp_client_socket.recv(1024)
recv_content = recv_data.decode("utf-8")
print("Recieved data: ", recv_content)
tcp_client_socket.close()
7. tcp服务端程序示例
- 示例
import socket
if __name__ == '__main__':
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
tcp_server_socket.bind(("", 9090))
tcp_server_socket.listen(128)
new_client, ip_port = tcp_server_socket.accept()
print("Client's ip and port: ", ip_port)
recv_data = new_client.recv(1024)
recv_content = recv_data.decode("utf-8")
print("Recieved Content: ", recv_content)
send_content = "......"
send_data = send_content.encode("utf-8")
new_client.send(send_data)
new_client.close()
tcp_server_socket.close()
8. 端口号复用
- 当客户端和服务端建立连接后,服务端程序退出后端口后不会立即释放,需要等待大概1~2分钟。
- 解决方法:
- 更换服务端端口号
- 设置端口号复用(推荐),让服务端程序退出后,端口号立即释放。
- 示例
参照【7. tcp服务端程序示例】
9. tcp网络应用程序的注意点
- 当客户端的套接字调用close后,服务器端的recv会解阻塞,返回的数据长度为0,服务端可以根据返回的数据长度来判断客户端是否已经下线,反之服务端关闭套接字,客户端的recv也会解阻塞,返回的数据长度也为0。
10. tcp服务端服务于多个客户端示例
- 示例
import socket
if __name__ == '__main__':
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
tcp_server_socket.bind(("", 9090))
tcp_server_socket.listen(128)
while:
new_client, ip_port = tcp_server_socket.accept()
print("Client's ip and port: ", ip_port)
recv_data = new_client.recv(1024)
recv_content = recv_data.decode("utf-8")
print("Recieved Content: ", recv_content)
send_content = "......"
send_data = send_content.encode("utf-8")
new_client.send(send_data)
new_client.close()
tcp_server_socket.close()
11. 多人版tcp服务端示例
- 示例
import socket
import threading
def handle_client_request(ip_port, new_client):
print("Client's ip and port: ", ip_port)
while:
recv_data = new_client.recv(1024)
if recv_data:
recv_content = recv_data.decode("utf-8")
print("Recieved Content: ", recv_content, ip_port)
send_content = "......"
send_data = send_content.encode("utf-8")
new_client.send(send_data)
else:
break
new_client.close()
if __name__ == '__main__':
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
tcp_server_socket.bind(("", 9090))
tcp_server_socket.listen(128)
while:
new_client, ip_port = tcp_server_socket.accept()
sub_thread = threading.Thread(target=handle_client_request, args=(ip_port, new_client))
sub_thread.setDaemon(True)
sub_thread.start()
tcp_server_socket.close()
发布了13 篇原创文章 ·
获赞 2 ·
访问量 810
转载自blog.csdn.net/ccblogs/article/details/104638245