socket01最小量代码

simple_socket/server.py

# -.- coding:utf-8 -.-
import socket

HOST = '127.0.0.1'
PORT = 50007
EOL1 = b'\r\n'
EOL2 = b'\r\n\r\n'

sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((HOST, PORT))
sock.listen(1)

while True:
    try:
        data = b''
        connection, address = sock.accept()
        while True:
            data += connection.recv(4096)
            if EOL1 in data or EOL2 in data:
                break
        connection.sendall(data)
        connection.close()
    finally:
        connection.close()

simple_socket/client.py

# -.- coding:utf-8 -.-
import socket

host = '127.0.0.1'
port = 50007
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((host, port))
    s.sendall(b'Hello, world')
    data = s.recv(4096)

print('Received:', data)

运行

# 启动服务 server.py
python simple_socket/server.py

# 运行客户端 client.py
python simple_socket/client.py

# 显示结果
Received: b'Hello, world'

AddressFamily

网络协议
  • socket.AF_UNIX 表示linux/unix套接字协议
  • socket.AF_INET 表示ipv4协议
  • socket.AF_INET6 表示ipv6协议
网络类型
  • socket.SOCK_STREAM 表示仅支持tcp类型
  • socket.SOCK_DGRAM 表示仅支持udp类型
  • socket.RAW
    表示支持tcp和udp两种类型, 但结构体和checksum需自行编码计算
    想了解更多raw类型编程,请参考这里。
套接字(socket.AF_UNIX)

套接字协议是操作系统在文件系统上创建一个socket文件,所有信息都是通过该文件来传输,也就是说套接字通常只能被同一台机器上的不同进程读取;据说由于它的机制相对比较简单,所以会比socket.INET(完整的ipv4协议)要快。
若采用套接字模式提供服务,而且又要可以被外部访问,那么利用nginx的proxy_pass参数可以满足这个要求;下面列出一个套接字的代码样例。

main.py

# -.- coding:utf-8 -.-
import tornado.ioloop
import tornado.web
from tornado import httpserver
from tornado.netutil import bind_unix_socket


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")


def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])


if __name__ == "__main__":
    app = make_app()
    server = httpserver.HTTPServer(app, xheaders=True)
    socket = bind_unix_socket('/tmp/main_tornado.sock', mode=0o666)
    server.add_socket(socket)
    tornado.ioloop.IOLoop.current().start()

运行

[root@localhost unix_socket]# python main.py

# 开启另外一个窗口来访问.
[root@localhost simple_socket]# curl --unix-socket /tmp/main_tornado.sock http://localhost/

# 显示信息
Hello, world

参考

  • [x] python socket example
  • [x] AF_UNIX和AF_INET比较

你可能感兴趣的:(socket01最小量代码)