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)
運(yùn)行
# 啟動服務(wù) server.py
python simple_socket/server.py
# 運(yùn)行客戶端 client.py
python simple_socket/client.py
# 顯示結(jié)果
Received: b'Hello, world'
AddressFamily
網(wǎng)絡(luò)協(xié)議
- socket.AF_UNIX 表示linux/unix套接字協(xié)議
- socket.AF_INET 表示ipv4協(xié)議
- socket.AF_INET6 表示ipv6協(xié)議
網(wǎng)絡(luò)類型
- socket.SOCK_STREAM 表示僅支持tcp類型
- socket.SOCK_DGRAM 表示僅支持udp類型
- socket.RAW
表示支持tcp和udp兩種類型, 但結(jié)構(gòu)體和checksum需自行編碼計(jì)算
想了解更多raw類型編程,請參考這里。
套接字(socket.AF_UNIX)
套接字協(xié)議是操作系統(tǒng)在文件系統(tǒng)上創(chuàng)建一個socket文件,所有信息都是通過該文件來傳輸,也就是說套接字通常只能被同一臺機(jī)器上的不同進(jìn)程讀取;據(jù)說由于它的機(jī)制相對比較簡單,所以會比socket.INET(完整的ipv4協(xié)議)要快。
若采用套接字模式提供服務(wù),而且又要可以被外部訪問,那么利用nginx的proxy_pass參數(shù)可以滿足這個要求;下面列出一個套接字的代碼樣例。
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()
運(yùn)行
[root@localhost unix_socket]# python main.py
# 開啟另外一個窗口來訪問.
[root@localhost simple_socket]# curl --unix-socket /tmp/main_tornado.sock http://localhost/
# 顯示信息
Hello, world