网络接口api

#服务端
import socket,sys
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host = socket.gethostname()
port = 8060
server.bind((host,port))
server.listen()
while True:
    client,addr = server.accept()
    print('连接地址:',str(addr))
    while True:
        data = client.recv(1024)
        print('Client(reciver):',data.decode())
        msg = input('Server(Send):')
        client.send(msg.encode('utf-8'))
client.close()
#客户端
import socket,sys
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host = socket.gethostname()
port = 8060
client.connect((host,port))
while True:
    msg = input('Client(Send):')
    client.send(msg.encode('utf-8'))
    rec = client.recv(1024)
    print('Server(reciver):',rec.decode())
client.close()

系统调用过程中,其中和网络有关的系统调用信息如下:

socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3 
connect(3, {sa_family=AF_INET, sin_port=htons(1234), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
sendto(3, "Hello,I'm liu", 13, 0, NULL, 0) = 13
recvfrom(3, "Hi,liu", 1024, 0, NULL, NULL) = 6
write(1, "Hi,liu\n", 7Hi,liu) = 7
close(3) = 0

可以从这些信息中看的python提供的网络接口API和Linux Socket API间一一对应的关系:

  • 在通过socket.socket()创建套接字时,底层调用的是socket()这个API,创建的套接字文件描述符是3(Shell启动的进程会打开三个与标准输入输出相关的文件,描述符为0,1,2)。
  • socket.connect()对应的是connect() API,第一个参数指明文件描述符3,即在前面创建的套接字上建立连接,然后python帮我们自动填充了sockaddr类型的结构体。
  • 可以看到,尽管创建的是流式套接字,但底层发送、接收数据还是使用的sendto和recvfrom,不过后两个参数(目的/源地址及其长度)被设为了NULL,《Unix网络编程》中说,在TCP中,connect函数调用后可以使用sendto及recvfrom,但还是不清楚python为什么这样实现socket.send()和socket.recv()。

你可能感兴趣的:(网络接口api)