Skip to content

网络编程 #16

@eziceice

Description

@eziceice

Socket

  • 网络编程中的一个基本组建是socket, 它是一个信息通道, 两端各有一个程序. 这些程序可能位于(通过网络相连的)不同的计算机上, 通过socket向对方发送信息. 在Python中, 大多数网络编程都隐藏了模块socket的基本工作原理, 不与socket直接交互.

    1. Socket分为两类, Server socket和Client socket. 创建了服务端的socket后,就可以让它等待连接请求的到来. 这样, 它将在某个网络地址(由IP和Port组成)处监听, 直到客户端的socket与之建立连接. 这样客户端和服务端就能与之通信了.

    2. 通常客户端的socket处理起来比较容易,因为它只需要完成任务并且断开连接. 而服务端的socket略微复杂一些, 因为服务器必须准备随时处理客户端的连接,并且还必须可以处理多个连接.

    3. Python中的socket存在于socket module中, 实例化socket时最多可指定三个参数: 一个地址族(默认为socket.AF_INET), 一个是流socket(socket.SOCK_STREAM,默认设置)还是数据报socket(socket.SOCK_DGRAM), 还有一个是协议(默认值0). 创建普通socket时,不需要提供任何参数.

    4. 服务器端的socket先调用bind方法绑定host IP和Port, 再使用listen来监听特定的地址. 然后, 客户端的socket就可以连接至服务器了, 办法是调用方法connect并提供调用方式bind时指定的地址(在服务器端, 可使用方法socket.gethostname获取当前机器的主机名). 这里的地址是一个格式为(host ,port)的tuple, host为主机名(如www.example.com), 而port是端口号(一个整数). 方法listen接受一个参数 - 待办任务清单的长度(即最多可有多少个连接在队列中等待接纳, 到达这个数量后将开始拒绝连接).

    5. 服务器socket开始监听后, 就可以接受客户端的连接了, 这是使用方法accept来完成的. 这个方法将阻断(同步式的)到客户端连接的到来, 然后返回一个格式为(client, address)的tuple. 其中client是一个客户端的socket, 而address是前面的地址解释过的地址. 服务器能以其认为合适的方式处理客户端的连接,然后再次调用accept以接着等待新连接的到来. 这通常是在一个无限循环中完成的.

    6. 为了在服务端和客户端传输数据, socket主要有两种方法: send和recv. 发送数据可使用send并提供一个字符串; 而接收数据, 可以调用recv并指定最多接收多少个字节的数据.

    7. 在Linux或者Unix系统中, 需要有管理员权限才能使用1024以下的port, 这些较小的port都是提供标准服务使用的. 比如port 80是提供web服务器的使用.

import socket
import threading

class MyThread(threading.Thread):
    def run(self):
        create_server()

def create_server():
    s = socket.socket()
    host = socket.gethostname()
    port = 1234
    s.bind((host, port))
    s.listen(5)
    while True:
        c, addr = s.accept()
        print('Got connection from', addr)
        message = 'Thanks for your messages'
        c.send(message.encode())
        c.close()

def create_client():
    s = socket.socket()
    host = socket.gethostname()
    port = 1234
    s.connect((host, port))
    print(s.recv(1024))

def main():
    t = MyThread()
    t.start()
    create_client()

if __name__ == '__main__':
    main()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions