Привет! Как поставщик сокетов, я воочию убедился в важности использования неблокирующих сокетов в различных приложениях. В этом блоге я расскажу вам, как использовать неблокирующие сокеты, а также расскажу немного о замечательных сокетах, которые мы предлагаем.
Что такое неблокирующие сокеты?
Прежде чем мы углубимся в использование неблокирующих сокетов, давайте быстро разберемся, что они из себя представляют. Традиционные сокеты блокируются, а это означает, что при вызове функции типаполучение()илиотправлять(), ваша программа остановится и будет ждать завершения операции. Это может быть настоящей проблемой, особенно в приложениях, где вам необходимо обрабатывать несколько подключений или выполнять другие задачи одновременно.
С другой стороны, неблокирующие сокеты не блокируют выполнение вашей программы. Когда вы вызываете функцию в неблокирующем сокете, она немедленно возвращает значение, даже если операция не завершена. Это позволяет вашей программе продолжать выполнять другие действия, ожидая завершения операции сокета.
Настройка неблокирующих сокетов
Первым шагом в использовании неблокирующих сокетов является создание сокета и установка для него неблокирующего режима. В Python это можно сделать так:
import сокет # Создать объект сокета sock =ocket.socket(socket.AF_INET,ocket.SOCK_STREAM) # Установить сокет в неблокирующий режим sock.setblocking(0)
В C этот процесс немного сложнее, но все же прост:
#include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <fcntl.h> #include <unistd.h> #include <arpa/inet.h> int main() { int sockfd; структура sockaddr_in server_addr; // Создаём сокет sockfd =ocket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("не удалось создать сокет"); вернуть -1; } // Устанавливаем сокет в неблокирующий режим int flags = fcntl(sockfd, F_GETFL, 0); fcntl(sockfd, F_SETFL, флаги | O_NONBLOCK); // Остальная часть вашего кода... return 0; }
Обработка неблокирующих операций
После того как вы перевели сокет в неблокирующий режим, вам необходимо осторожно обращаться с операциями. Когда ты звонишьполучение()илиотправлять()в неблокирующем сокете он может вернуть ошибку, если операцию невозможно завершить немедленно. В большинстве случаев эта ошибка будетЭВУЛДБЛОКилиЭГЕЙН.
В Python вы можете справиться с этим следующим образом:
try: data = sock.recv(1024) if data: print(f"Received: {data}") кроме socket.error as e: if e.errno in (socket.EWOULDBLOCK, socket.EAGAIN): # Данные пока недоступны, продолжайте выполнять другие задачи, pass else: # Обработка других ошибок print(f"Error: {e}")
В C это аналогично:
#include <errno.h> //... char buffer[1024]; ssize_t n = Recv (sockfd, буфер, sizeof (буфер), 0); if (n < 0) { if (errno == EWOULDBLOCK || errno == EAGAIN) { // Данных пока нет, продолжаем выполнять другие задачи } else { // Обрабатываем другие ошибки perror("recv"); } } else if (n > 0) {uffer[n] = '\0'; printf("Получено: %s\n", буфер); }
Использование неблокирующих сокетов для нескольких соединений
Одним из основных преимуществ неблокирующих сокетов является то, что они позволяют обрабатывать несколько соединений одновременно. Вы можете использовать метод опроса, чтобы проверить, есть ли какая-либо активность в нескольких сокетах.
В Python вы можете использоватьвыбиратьмодуль:


import select # Список сокетов для мониторинга входов = [sock1, sock2] while True: доступны для чтения, записи, исключительные = select.select(inputs, [], inputs) for s в readable: try: data = s.recv(1024) if data: print(f"Received from {s}: {data}") кроме socket.error as e: if e.errno in (socket.EWOULDBLOCK, сокет.EAGAIN): pass else: print(f"Error: {e}") inputs.remove(s) s.close() для s в исключительных случаях: inputs.remove(s) s.close()
В C вы можете использоватьвыбирать()функция:
#include <sys/select.h> //... fd_set readfds; интервал max_fd; // Инициализируем набор файловых дескрипторов FD_ZERO(&readfds); FD_SET(sockfd1, &readfds); FD_SET(sockfd2, &readfds); max_fd = (sockfd1 > sockfd2)? соккфд1: соккфд2; в то время как (1) { fd_set tmpfds = readfds; int Activity = select(max_fd + 1, &tmpfds, NULL, NULL, NULL); если (активность < 0) { perror("выбрать"); перерыв; } for (int i = 0; i <= max_fd; i++) { if (FD_ISSET(i, &tmpfds)) { char buffer[1024]; ssize_t n = Recv (я, буфер, sizeof (буфер), 0); if (n <0) { if (errno == EWOULDBLOCK || errno == EAGAIN) { continue; } Еще {perror("recv"); FD_CLR(я, &readfds); закрыть (я); } } else if (n > 0) {uffer[n] = '\0'; printf("Получено от %d: %s\n", i, буфер); } } } }
Наши предложения розеток
Как поставщик розеток, мы предлагаем широкий ассортимент розеток, отвечающих вашим потребностям. Ознакомьтесь с нашимУдарные головки, которые предназначены для работы в условиях высокого крутящего момента. У нас также естьГорячекованые ручные розетки, которые изготавливаются с использованием процесса горячей ковки для обеспечения превосходной прочности и долговечности. И конечно, нашРучные розеткиидеально подходят для общего использования.
Заключение
Неблокирующие сокеты — это мощный инструмент, который может значительно повысить производительность ваших сетевых приложений. Позволив вашей программе продолжать выполнение во время ожидания завершения операций сокета, вы сможете более эффективно обрабатывать несколько соединений и одновременно выполнять другие задачи.
Если вы заинтересованы в приобретении высококачественных розеток для своих проектов, не стесняйтесь обращаться к обсуждению закупок. Мы здесь, чтобы помочь вам найти подходящие розетки для ваших нужд.
Ссылки
- «Сетевое программирование UNIX, Том 1: API сетевых сокетов», У. Ричард Стивенс
- Официальная документация Python по
розеткаивыбиратьмодули - Документация стандартной библиотеки C по функциям программирования сокетов

