做一个技术girl

导航

socket

一、socket

1.什么是socket

在应用层和传输层之间,是一组封装了TCP/UDP协议的接口,让socket组织数据和传输数据。

2.客户端和服务器都要使用socket对象

缓冲区:

1、作为发送方,数据一定先给到操作系统,而操作系统不可能同时处理,所以操作系统需要一个缓冲区,先将数据放到缓冲区,操作系统会自己到缓冲区拿数据进行处理 2、作为接收方,数据也是先入操作系统的缓冲区,操作系统到缓冲区拿取数据给应用程序

s.bind()
s.listen()
s.accept()
#客户端
s.connect()

#公共函数
s.recv()
s.send()  #发送tcp数据

s.senall()#发送完整的tcp数据
s.recvrom() #接收udp数据
s.sento()  #发送udp数据

 

3.基于TCP的socket

(1)基础版

#服务器端
import socket
server=socket.socket()

server.bind(("127.0.0.1",9899))
server.listen()
client,addr=server.accept()
data=client.recv(1024)
print("收到客户端发来的数据%s"%data.decode("utf-8"))
client.send(data)
client.close()
server.close()

#客户端
import socket
client=socket.socket()
client.connect(("127.0.0.1",9899))
client.send("hello 服务器".encode("utf-8"))
data=client.recv(1024)
print("收到服务器%s"%data.decode("utf-8"))
client.close()

(2)循环版

#服务器端循环收发
import  socket
server=socket.socket()
server.bind(("127.0.0.1",9999))
server.listen()
while True:
   client,addr=server.accept()     #可以不断地接收新连接
   while True:
       try:
           data=client.recv(1024)
           if not data:
               client.close()
               break
           print("收到客户端发来的数据%s"%data.decode("utf-8"))
           client.send(data)
       except ConnectionResetError:
           print("客户端强行关闭了连接")
           client.close()
           break
client.close()
server.close()
#客户端循环收发
import socket
client=socket.socket()
client.connect(("127.0.0.1",9999))
while True:
   msg=input(">>>").strip()
   client.send(msg.encode("utf-8"))
   data=client.recv(1024)
   print("收到服务器%s"%data.decode("utf-8"))
client.close()

(3)异常处理

#服务器
import socket
server=socket.socket()
server.bind(("127.0.0.1",8889))
server.listen()
client,addr=server.accept()
while True:
   try:
       data=client.recv(1024)
       if not data:
           print("对方已关闭")
           break
       print("来自客户端的-----%s"%data.decode("utf-8"))
       client.send(data.upper())
   except ConnectionResetError:
       print("对方异常关闭连接")
client.close()
server.close()
#客户端
import socket
client=socket.socket()
client.connect(("127.0.0.1",8889))
client.send(input(">>>").encode("utf-8"))
data=client.recv(1024)
print("来自服务器的----%s"%data.decode("utf-8"))
client.close()

 

4.基于UDP的socket

#服务器
import socket
server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM,proto=0)
server.bind(("127.0.0.1",5666))
while True:
   data,addr=server.recvfrom(1024)   #阻塞,直到收到数据为止
   print("收到来自%s的消息:%s"%(data.decode("utf-8"),addr[0]))
   server.sendto(data.upper(),addr)

server.close()
#客户端1
import socket
client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)

while True:
   data=input(">>>").encode("utf-8")
   client.sendto(data,("127.0.0.1",5666))
   d,addr=client.recvfrom(1024)
   print(d.decode("utf-8"))
client.close()
#客户端2
import socket
client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)

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

 

5、半连接池

产生半连接的两种情况:

1、客户端无法 返回ACK信息;

2、服务器来不及处理客户端的连接请求。

有一种攻击叫syn洪水攻击,就是不断产生半连接,让服务器无法处理请求。

半连接池的作用:

半连接池就是一个容器,系统会自动将半连接放入这个容器中,可以避免半连接过多导致 资源耗光。

import socket
server=socket.socket()
server.listen(5)         #表示最多可以等5个连接
#服务器
import socket,time
server=socket.socket()
server.bind(("127.0.0.1",6667))
server.listen(1)
while True:
   time.sleep(0.5)
server.close()
#客户端1
import socket
client=socket.socket()
client.connect(("127.0.0.1",6667))

while True:
   client.send(input(">>>").encode("utf-8"))
   data=client.recv(1024)
   print(data.decode("utf-8"))

client.close()
#客户端2
import socket
client=socket.socket()
client.connect(("127.0.0.1",6667))

while True:
   client.send(input(">>>").encode("utf-8"))
   data=client.recv(1024)
   print(data.decode("utf-8"))

client.close()

 

分别运行服务器----客户端1----客户端2 结果为:

posted on 2018-12-25 21:09  戚戚~  阅读(145)  评论(0编辑  收藏  举报