您的位置:

Python Socket通信详解

Python是一种高级编程语言,具备力量强大的标准库,包括一组关于socket通信的类和函数。Python socket通信提供了一种简单而直接的交换数据方法,可以通过TCP或UDP创建一个连接并进行双向通信。

一、Python TCP通信

TCP(Transmission Control Protocol)是一种高可靠性的面向连接的协议,被常用于Web服务器、Email、FTP服务器等。Python socket模块提供了一组TCP通信相关的类和函数,同时也提供了一组示例代码。

import socket

#监听一个端口
def listen_port(port):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('', port))
    s.listen(1)
    while True:
        conn, addr = s.accept()
        print('Connection address:', addr)
        data = conn.recv(1024)
        if not data:
            break
        conn.sendall(data)
        conn.close()
listen_port(12345)

以上代码实现了一个TCP服务器示例代码,其中使用了socket.socket()创建了一个Socket对象,并调用bind()方法绑定到本地IP地址以及指定的端口号(12345)。使用listen()方法指定最大连接数,并使用accept()方法接受客户端连接请求。recv()方法用于接收客户端发送的数据,sendall()方法用于向客户端发送数据,在数据传输完毕后,使用close()方法关闭连接。

二、Python多线程通信

在实际应用中,需要同时处理多个连接,这时就需要使用多线程或多进程技术。Python提供了threading模块和socketserver模块来支持多线程通信。

import socket, threading

#监听一个端口
def listen_port(port):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('', port))
    s.listen(5)
    while True:
        conn, addr = s.accept()
        print('Connection address:', addr)
        t = threading.Thread(target=handle_client, args=(conn,))
        t.start()
#线程处理函数
def handle_client(conn):
    while True:
        data = conn.recv(1024)
        if not data:
            break
        conn.sendall(data)
    conn.close()
listen_port(12345)

以上代码实现了一个支持多线程的TCP服务器示例代码,其中每个客户端的连接请求被分别处理,将处理函数作为参数传递给新线程,并启动线程。

三、Python与C通信

在某些场景下,需要使用Python作为编写应用程序的用户界面,而底层的功能需要使用C语言实现。可以使用Python的ctypes模块和Socket通信来实现Python与C语言的通信。

下面是一个使用Python与C语言通信的实例。

#C语言代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define PORT 8080

int main(int argc, char const *argv[]) {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);

    char buffer[1024] = {0};
    char *hello = "Hello from server";

    // Creating socket file descriptor
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // Attaching socket to the port 8080
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
                &opt, sizeof(opt))) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons( PORT );

    // Forcefully attaching socket to the port 8080
    if (bind(server_fd, (struct sockaddr *)&address,
                sizeof(address)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }
    if (listen(server_fd, 3) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
                    (socklen_t*)&addrlen))<0) {
        perror("accept");
        exit(EXIT_FAILURE);
    }
    valread = read( new_socket , buffer, 1024);
    printf("%s\n",buffer );
    send(new_socket , hello , strlen(hello) , 0 );
    printf("Hello message sent\n");
    return 0;
}
#Python代码
import ctypes

#载入C语言动态库
lib = ctypes.CDLL('./libserver.so')
lib.go.argtypes = [ctypes.c_char_p]
lib.go.restype = None

#调用C函数
lib.go(b"Hello from Python")

以上代码实现了一个从Python调用C动态库的简单示例程序,两个程序通过Socket协议进行通信,在C语言中创建了一个Socket服务器,在Python中通过ctypes模块调用C语言中的动态库。

四、Python和Netty通信

Netty是一种基于Java的高性能异步事件驱动的网络应用框架,支持多协议通信服务的开发。Python支持通过Socket协议与Netty进行通信。

#Python代码
import socket

#连接到Netty服务器
server_address = ('localhost', 9090)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(server_address)

#发送消息到Netty服务器
message = 'Hello from Python'
sock.sendall(message.encode())

#接收Netty服务器发送的消息
data = sock.recv(1024)
sock.close()

print(data.decode('utf-8'))

以上代码实现了一个使用Python与Netty通信的示例程序,其中Python调用socket.socket()建立连接,并使用sendall()方法将消息发送给Netty服务器,最终调用recv()方法接收Netty发送的消息。

总结

通过以上的介绍,读者可以了解到Python Socket通信的基本原理和应用场景,并掌握了基本的Socket通信技术。