与tcp客户端的文章一同对比学习,了解运行过程,着重点在思考其中逻辑。
注意编码和解码,在客户端和服务端之间的转换。
1. 创建套接字
- sockfd=socket. socket( socket_ family=AF_ INET, socket type=SOCK STREAM, proto=0)
- 功能:创建套接字
参数: - socket_ family网络地址类型 AF INET表示ipv4
- socket_ type套接字类型 SOCK_ STREAM流式 SOCK_ _DGRAM 数据报
proto通常为0 选择 子协议 - 返回值:
套接字对象
2.绑定地址
sockfd. bind(addr)
功能:
绑定本机网络地址
参数:二元元组 (ip, port) ('0.0.0.0',8888)
3.设置监听
sockfd. listen(n)
- 功能:将套接字设置为监听套接字,确定监听队列大小
+参数:监听队列大小
4.等待处理客户端连接请求
connfd,addr = sockfd. accept( )
- 功能:阻塞 等待处理客户端请求
- 返回值:
connfd:客户端连接 套接字
addr:连接的客户端地址
5.消息收发
data = connfd. recv( buffersize)
- 功能:接受客户端消息
- 参数:每次最多接收消息的大小
- 返回值:接收到的内容
n = connfd. send(data )
- 功能:发送消息
- 参数:要发送的内容bytes格式
- 返回值:发送 的字节数
import socket
def main():
#买个手机(创建套接字)
tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#插个手机卡(绑定本地信息)
tcp_server_socket.bind(("0.0.0.0",7890))
#将手机设置为正常的响铃模式(让默认的套接字主动变为被动 listen)
tcp_server_socket.listen(128)
print("--1--")
#等待别人的电话来(等待客户端的连接 accept),监听套接字,负责等待有新的客户端进行连接,accept
#产生的新的套接字用来为客户端服务,client_Addr,谁给我打电话的ip和端口
new_client_socket,client_Addr = tcp_server_socket.accept()
print("--2--")
print(client_Addr)
#接收客户端发送过来的请求
recv_data = new_client_socket.recv(1024)
print(recv_data)
#回送一部分数据给客户端
new_client_socket.send("hahahaha--ok--".encode("gbk"))
#关闭套接字
new_client_socket.close()
tcp_server_socket.close()
if __name__ == "__main__":
main()
此时代码作为服务器来响应客户端的请求。按如下操作步骤
- 运行客户端(TCP服务器代码)
- 在网络调试助手中,选择协议类型,为TCP client,这时候网络调试助手作为客户端来发送请求
- 输入的是服务器的IP地址,也就是我这个代码,所在的局域网下的IP地址,因为我用的两台电脑
- 服务器端口,也是代码写的7890这个端口
- 输入发送的数据
-
因为我写了服务器给客户端返回的数据,所以只要发送过去数据,服务器就会返回“hahahahah--ok--”
解决在syn洪水攻击,和服务器高并发的情况下大量time_wait状态的优化方法,解决办法如下
tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcp_server_socket .setsockopt(SOL_SOCKET,SO_REUSEADDR,1)v#解释它,在bind前加
#插个手机卡(绑定本地信息)
tcp_server_socket.bind(("",7890))
tcp套接字数据传输特点
● tcp连接中当一端退出,另- -端如果阻塞在recv ,此时recv会立即返回一个空字串。
● tcp连接中如果一端已经不存在 ,让然试图通过send发送则会产生BrokenPipeErron
● 一个监听套接字可以同时连接多个客户端,也能够重复被连接