网络编程之socket编程

一.socket层

二.什么是socket

socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在socket接口后面,对用户来说,一组简单的接口就是全部,让socket去组织数据,以符合指定的协议。所以,我们无需深入理解tcp/ip协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵守tcp/udp标准的。

三.socket的作用

减少网络编程的工作量

四. 套接字家族

  1.基于文件类型的套接字家族   AF_UNIX

  2.基于网络类型的套接字家族 AF_INET

import socket
socket.socket(socket_family,socket_type,protocal=0)
socket_family 可以是 AF_UNIX 或 AF_INET。socket_type 可以是 SOCK_STREAM 或 SOCK_DGRAM。protocol 一般不填,默认值为 0。

获取tcp/ip套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

获取udp/ip套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

由于 socket 模块中有太多的属性。我们在这里破例使用了'from module import *'语句。使用 'from socket import *',我们就把 socket 模块里的所有属性都带到我们的命名空间里了,这样能 大幅减短我们的代码。
例如tcpSock = socket(AF_INET, SOCK_STREAM)
socket()的tcp与udpt用法

  默认不填参数默认为socket.AF_INET 与 socket.SOCK_STREAM

五.socket的用法

#服务器
import socket

server = socket.socket()

server.bind(("127.0.0.1",16680))

server.listen()

client,address = server.accept()

data = client.recv(1024)
print("来自客户端的数据:%s"%data.decode("utf-8"))
client.send(data)
client.close()

#客户端
import socket

client = socket.socket()

client.connect(("127.0.0.1",16680))

client.send("你好".encode("utf-8"))

data = client.recv(1024)
print("来自服务端的数据:%s"%data.decode("utf-8"))

client.close()
初级版tcp协议
#服务器
import socket
server = socket.socket()
server.bind(("127.0.0.1",16668))
server.listen()
while True:
    client,address = server.accept()
    while True:
        try:
            data = client.recv(1024)
            if not data:
                client.close()
                break
            print(data.decode("utf-8"))
            msg = input(">>>:").strip()
            client.send(msg.encode("utf-8"))
        except ConnectionResetError:
            print("客户端已经断开连接!")
            client.close()
            break

#客户端
import socket

client = socket.socket()
client.connect(("127.0.0.1",16668))

while True:
    msg = input(">>>:").strip()
    client.send(msg.encode("utf-8"))
    data = client.recv(1024)
    print(data.decode("utf-8"))
循环的tcp通讯,且客户端断开服务器不会报错,会一直等待连接请求,这个也是tcp通讯的模板
#服务器
import socket

server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
server.bind(("127.0.0.1",16668))

while True:
    data,address = server.recvfrom(1024)

    print("收到来自%s的数据:%s"%(address[0],data.decode('utf-8')))
    msg = input(">>>:").strip()
    server.sendto(msg.encode("utf-8"),address)

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

while True:
    msg = input(">>>:").strip()
    client.sendto(msg.encode("utf-8"),("127.0.0.1",16668))
    data,address = client.recvfrom(1024)
    print("收到来自服务器%s的数据:%s"%(address[0],data.decode("utf-8")))

#客户端2
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)

while True:
    msg = input(">>>:").strip()
    client.sendto(msg.encode("utf-8"),("127.0.0.1",16668))
    data,address = client.recvfrom(1024)
    print("收到来自服务器%s的数据:%s"%(address[0],data.decode("utf-8")))
udp通讯模板,可以多个客户端和服务器一起通讯

六. 半连接池

  半连接是指当服务器在响应了客户端的第一次请求后,会进入等待状态,等待客户端发送的ack信息,这时候这个连接就称之为半连接。

  产生半连接的两种情况:

      1.客户端无法返回ACK信息

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

  有一种黑客攻击叫做syn洪水攻击,就是不断产生半连接,使服务器无法处理请求,随着半连接的增多,服务器就会奔溃。

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

  服务器的listen()中可以选择填参数,是指最多允许几个客户端连接服务器,即允许这么多个半连接,当有这么多个客户端时,再来一个客户端请求连接服务器,会被拒绝。

posted on 2019-01-03 14:38  黑粥  阅读(164)  评论(0编辑  收藏  举报

导航