Python语言下简单socket程序报告
1 什么是Socket
在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据
socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。
我的理解就是Socket就是该模式的一个实现:即socket是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。
2 socket服务器端代码及其解释
import socket HOST = '127.0.0.1' PORT = 8888 server = socket.socket() server.bind((HOST, PORT)) server.listen(1) print(f'the server is listening at {HOST}:{PORT}') print('waiting for conntection...')
conn, addr = server.accept() print(f'connect success addr={addr}') print('waiting for message') while True: msg = conn.recv(1024) print('the clint send:', msg.decode()) response = input('enter your response: ') conn.send(response.encode()) print('waiting for answer')
分析该程序:
首先,sever为一个实例化的socket套接字,随后server绑定到本地地址,以用户名:端口号的方式给出。随后对该端口进行监听。
一旦收到回复,会以元组的形式返回一个连接对象conn与地址addr。这里注意到addr地址以元组(IPaddr,port)的形式给出。随后就可以利用conn进行通信了
3 socket客户端代码及其解释
import socket import sys try: host, port = input('enter host address like host:port: ').split(':') except ValueError: print('the address is wrong') sys.exit(-1) if len(host) == 0 or len(port) == 0: print('the address is wrong') sys.exit(-1) else: client = socket.create_connection((host, port)) print('connect successfully. waiting for response...') client.send(b'hello server.') while True: response = client.recv(1024) print('the response is:', response.decode()) msg = input('please enter a answer: ') client.send(msg.encode()) print('waiting for response...')
首先,请用户输入地址,端口号,之后以“:”为间隔分开。如果输入出错则抛出ValueError。如果是正确的地址则创建连接。
随后在连接中进行通信。
结果大概如下图所示:
server端:

client端:

可以看见能够成功运行
4 相关API及分析:
Python下我们重点分析socket接口对象。
在socket.pyi中,我们找到如下的socket类及方法定义:
class socket: family: int type: int proto: int if sys.version_info < (3,): def __init__(self, family: int = ..., type: int = ..., proto: int = ...) -> None: ... else: def __init__(self, family: int = ..., type: int = ..., proto: int = ..., fileno: Optional[int] = ...) -> None: ... if sys.version_info >= (3, 2): def __enter__(self: _SelfT) -> _SelfT: ... def __exit__(self, *args: Any) -> None: ... # --- methods --- # second tuple item is an address def accept(self) -> Tuple[socket, Any]: ... def bind(self, address: Union[tuple, str, bytes]) -> None: ... def close(self) -> None: ... def connect(self, address: Union[tuple, str, bytes]) -> None: ... def connect_ex(self, address: Union[tuple, str, bytes]) -> int: ... def detach(self) -> int: ... def fileno(self) -> int: ...
该类中详细定义了对于网络接口的使用规范。我们重点查看connect函数,其定义如下:
def connect(self, addr): """Connects to remote ADDR, and then wraps the connection in an SSL channel.""" self._real_connect(addr, False)
这里提供SSL加密的安全连接,我们继续查看_real_connect()内置方法:
def _real_connect(self, addr, connect_ex): if self.server_side: raise ValueError("can't connect in server-side mode") # Here we assume that the socket is client-side, and not # connected at the time of the call. We connect it, then wrap it. if self._connected: raise ValueError("attempt to connect already-connected SSLSocket!") sslobj = self.context._wrap_socket(self, False, self.server_hostname) self._sslobj = SSLObject(sslobj, owner=self, session=self._session) try: if connect_ex: rc = socket.connect_ex(self, addr) else: rc = None socket.connect(self, addr) if not rc: self._connected = True if self.do_handshake_on_connect: self.do_handshake() return rc except (OSError, ValueError): self._sslobj = None raise
同函数中注释所说明的,该函数假设自己处在客户端并且没有对于目标地址的连接。该函数目的为连接到指定地址并调用相关的SSL对象对该链接进行封装。
5 Linux Socket API
因为在Python语言中,实现我上述程序的网络端口也是socket套接字,其内置方法与Linux Socket较为相似,包括bind()、 connect()等方法,差别仅仅在于实现这些函数的语言不同。
在逻辑与功能设计层面,两者思想是相似甚至相同的。

浙公网安备 33010602011771号