Python TCP 서버 만 드 는 방법

5763 단어 Python창설TCP서버
문제.
TCP 프로 토 콜 을 통 해 클 라 이언 트 와 통신 하 는 서버 를 실현 하고 싶 습 니 다.
해결 방안
TCP 서버 를 만 드 는 간단 한 방법 은 socketserver 라 이브 러 리 를 사용 하 는 것 입 니 다.예 를 들 어 다음은 간단 한 응답 서버 입 니 다.

from socketserver import BaseRequestHandler, TCPServer

class EchoHandler(BaseRequestHandler):
  def handle(self):
    print('Got connection from', self.client_address)
    while True:

      msg = self.request.recv(8192)
      if not msg:
        break
      self.request.send(msg)

if __name__ == '__main__':
  serv = TCPServer(('', 20000), EchoHandler)
  serv.serve_forever()
이 코드 에서 클 라 이언 트 연결 서 비 스 를 위 한 특수 한 처리 클래스 를 정 의 했 습 니 다.handle()방법 을 실 현 했 습 니 다.request 속성 은 클 라 이언 트 socket,clientaddress 에 클 라 이언 트 주소 가 있 습 니 다.이 서버 를 테스트 하기 위해 실행 하고 다른 Python 프로 세 스 를 열 어 서버 에 연결 합 니 다.

>>> from socket import socket, AF_INET, SOCK_STREAM
>>> s = socket(AF_INET, SOCK_STREAM)
>>> s.connect(('localhost', 20000))
>>> s.send(b'Hello')
5
>>> s.recv(8192)
b'Hello'
>>>
다른 프로 세 서 를 쉽게 정의 할 수 있 는 경우 가 많다.다음은 StreamRequestHandler 기본 클래스 를 사용 하여 클래스 파일 인 터 페 이 스 를 바 텀 socket 에 배치 하 는 예 입 니 다.

from socketserver import StreamRequestHandler, TCPServer

class EchoHandler(StreamRequestHandler):
  def handle(self):
    print('Got connection from', self.client_address)
    # self.rfile is a file-like object for reading
    for line in self.rfile:
      # self.wfile is a file-like object for writing
      self.wfile.write(line)

if __name__ == '__main__':
  serv = TCPServer(('', 20000), EchoHandler)
  serv.serve_forever()
토론 하 다.
socketserver 는 간단 한 TCP 서버 를 쉽게 만 들 수 있 습 니 다.그러나 주의해 야 할 것 은 기본 적 인 상황 에서 이 서버 는 단일 스 레 드 이 고 한 번 에 한 클 라 이언 트 에 만 서 비 스 를 연결 할 수 있 습 니 다.여러 클 라 이언 트 를 처리 하려 면 Forking TCPServer 나 ThreadingTCPServer 대상 을 초기 화 할 수 있 습 니 다.예 를 들 면:

from socketserver import ThreadingTCPServer


if __name__ == '__main__':
  serv = ThreadingTCPServer(('', 20000), EchoHandler)
  serv.serve_forever()
fork 나 스 레 드 서버 를 사용 하 는 잠재 적 인 문 제 는 모든 클 라 이언 트 연결 에 새로운 프로 세 스 나 스 레 드 를 만 드 는 것 입 니 다.클 라 이언 트 연결 수 는 제한 이 없 기 때문에 악의 적 인 해커 는 대량의 연결 을 동시에 보 내 서버 를 무 너 뜨 릴 수 있다.
이 문제 가 걱정 된다 면 미리 크기 를 할당 하 는 작업 스 레 드 풀 이나 프로 세 스 풀 을 만 들 수 있 습 니 다.일반 비 스 레 드 서버 를 만 든 다음 스 레 드 풀 에서 server 를 사용 하 십시오.forever()방법 으로 시작 합 니 다.

if __name__ == '__main__':
  from threading import Thread
  NWORKERS = 16
  serv = TCPServer(('', 20000), EchoHandler)
  for n in range(NWORKERS):
    t = Thread(target=serv.serve_forever)
    t.daemon = True
    t.start()
  serv.serve_forever()
일반적으로 TCPServer 는 예화 할 때 해당 socket 을 연결 하고 활성화 합 니 다.그러나,때때로 당신 은 어떤 옵션 을 설정 해서 아래 의 socket 을 조정 하려 고 합 니 다.매개 변수 bid 를 설정 할 수 있 습 니 다.and_activate=False 。다음 과 같다.

if __name__ == '__main__':
  serv = TCPServer(('', 20000), EchoHandler, bind_and_activate=False)
  # Set up various socket options
  serv.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
  # Bind and activate
  serv.server_bind()
  serv.server_activate()
  serv.serve_forever()
위의 socket 옵션 은 서버 가 이전에 사 용 했 던 포트 번 호 를 다시 연결 할 수 있 도록 매우 보편적 인 설정 항목 입 니 다.자주 사용 되 기 때문에 클래스 변수 에 배치 되 어 TCPServer 에 직접 설정 할 수 있 습 니 다.서버 를 예화 할 때 값 을 설정 합 니 다.다음 과 같 습 니 다.

if __name__ == '__main__':
  TCPServer.allow_reuse_address = True
  serv = TCPServer(('', 20000), EchoHandler)
  serv.serve_forever()
위의 예제 에서 우 리 는 두 가지 서로 다른 프로세서 기본 클래스(BaseRequestHandler 와 StreamRequestHandler)를 보 여 주 었 다.StreamRequestHandler 는 다른 클래스 변 수 를 설정 하여 새로운 기능 을 지원 할 수 있 습 니 다.예 를 들 면:

import socket

class EchoHandler(StreamRequestHandler):
  # Optional settings (defaults shown)
  timeout = 5           # Timeout on all socket operations
  rbufsize = -1          # Read buffer size
  wbufsize = 0           # Write buffer size
  disable_nagle_algorithm = False # Sets TCP_NODELAY socket option
  def handle(self):
    print('Got connection from', self.client_address)
    try:
      for line in self.rfile:
        # self.wfile is a file-like object for writing
        self.wfile.write(line)
    except socket.timeout:
      print('Timed out!')
마지막 으로 주의해 야 할 것 은 대부분의 Python 의 고 층 네트워크 모듈(예 를 들 어 HTTP,XML-RPC 등)이 socketserver 기능 위 에 세 워 져 있다 는 것 이다.즉,socket 라 이브 러 리 를 직접 사용 하여 서버 를 실현 하 는 것 도 어렵 지 않다 는 것 이다.다음은 socket 을 사용 하여 직접 프로 그래 밍 한 서버 의 간단 한 예 입 니 다.

from socket import socket, AF_INET, SOCK_STREAM

def echo_handler(address, client_sock):
  print('Got connection from {}'.format(address))
  while True:
    msg = client_sock.recv(8192)
    if not msg:
      break
    client_sock.sendall(msg)
  client_sock.close()

def echo_server(address, backlog=5):
  sock = socket(AF_INET, SOCK_STREAM)
  sock.bind(address)
  sock.listen(backlog)
  while True:
    client_sock, client_addr = sock.accept()
    echo_handler(client_addr, client_sock)

if __name__ == '__main__':
  echo_server(('', 20000))
이상 은 Python 이 TCP 서버 를 만 드 는 방법 에 대한 상세 한 내용 입 니 다.Python 이 TCP 서버 를 만 드 는 방법 에 대한 더 많은 자 료 는 저희 의 다른 관련 글 을 주목 하 십시오!

좋은 웹페이지 즐겨찾기