>  기사  >  백엔드 개발  >  Python 고급 소켓 자세한 설명

Python 고급 소켓 자세한 설명

高洛峰
高洛峰원래의
2016-10-17 16:13:55982검색

소켓(Socket)의 원래 영어 의미는 "구멍" 또는 "소켓"입니다. BSD UNIX의 프로세스 통신 메커니즘으로 일반적으로 "소켓"이라고도 하며 IP 주소와 포트를 설명하는 데 사용됩니다. 통신 체인의 핸들이며 서로 다른 가상 머신 또는 서로 다른 컴퓨터 간의 통신을 구현하는 데 사용할 수 있습니다. .

네트워크상의 두 프로그램은 양방향 통신 연결을 통해 데이터를 교환합니다. 이 연결의 한쪽 끝을 소켓이라고 합니다.

네트워크 통신 연결을 설정하려면 최소한 한 쌍의 포트 번호(소켓)가 필요합니다. 소켓은 본질적으로 TCP/IP를 캡슐화하는 프로그래밍 인터페이스(API)입니다. TCP/IP는 프로그래머가 네트워크 개발에 사용할 수 있는 인터페이스도 제공합니다. HTTP는 캡슐화하거나 표시하는 방법을 제공하는 자동차입니다. 데이터 특정 형식, 소켓은 네트워크 통신 기능을 제공하는 엔진입니다.

파이썬의 소켓에 대해 이야기해보겠습니다.

1.socket 모듈

소켓을 생성하려면 소켓.socket() 함수를 사용하세요. 구문은 다음과 같습니다:

socket.socket(socket_family,socket_type,protocol=0)


socket_family는 다음 매개변수일 수 있습니다.


socket.AF_INET IPv4(기본값)

socket.AF_INET6 IPv6


socket.AF_UNIX만 사용할 수 있습니다. 단일 Unix 시스템에서 프로세스 간 통신


socket_type은 다음 매개변수일 수 있습니다.


소켓.SOCK_STREAM 스트리밍 소켓, TCP용(기본값)

소켓.SOCK_DGRAM 데이터그램 소켓, UDP용


소켓.SOCK_RAW 원시 소켓, 일반 소켓은 ICMP, IGMP 및 다른 네트워크 메시지는 가능하지만 SOCK_RAW는 또한 특수 IPv4 메시지도 처리할 수 있습니다. 또한 원시 소켓을 사용하면 IP_HDRINCL 소켓 옵션을 통해 IP 헤더를 구성할 수 있습니다.

Socket.SOCK_RDM은 신뢰할 수 있는 UDP 형식으로 데이터그램 전달을 보장하지만 순서를 보장하지는 않습니다. SOCK_RAM은 원래 프로토콜에 대한 낮은 수준의 액세스를 제공하는 데 사용되며 ICMP 메시지 전송과 같은 특정 특수 작업을 수행해야 할 때 사용됩니다. SOCK_RAM은 일반적으로 고급 사용자나 관리자가 실행하는 프로그램으로 제한됩니다.

 socket.SOCK_SEQPACKET 안정적인 연속 패킷 서비스


프로토콜 매개변수:


 0 (기본값) 특정 주소 패밀리와 연관된 프로토콜입니다. 0인 경우 시스템은 주소 형식 및 소켓 카테고리에 따라 자동으로 적절한 프로토콜을 선택합니다.


2. -in 메소드


서버 측 소켓 기능


s.bind() 바인딩 주소(ip 주소, 포트) )을 소켓에 연결하려면 매개변수가 튜플 형식이어야 합니다. 예: s.bind(('127.0.0.1',8009))


s.listen( 5) 듣기 시작, 5는 보류 중인 최대 연결 수입니다


s.accept() 클라이언트 연결을 수동적으로 수락하고 연결을 차단하고 대기합니다


클라이언트 소켓 기능


s.connect() 서버에 연결하려면 매개변수가 튜플 형식이어야 합니다. 예: s. connect(('127,0.0.1',8009))


공용 소켓 기능


s .recv(1024) TCP 데이터 수신, 1024는 데이터 수신 1회 크기


s.send(bytes) TCP 데이터 송신, python3 데이터 송신 형식이어야 함 바이트 형식


s.sendall() 데이터를 완전히 전송하고 내부 루프 호출은 send


s를 호출합니다. .close () 소켓 닫기


예제 1. 소켓 프로그램의 간단한 구현

서버측

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socket
import time
IP_PORT = ('127.0.0.1',8009)
BUF_SIZE = 1024
  
tcp_server = socket.socket()
tcp_server.bind(IP_PORT)
tcp_server.listen(5)
  
while True:
    print("waiting for connection...")
    conn,addr = tcp_server.accept()
    print("...connected from:",addr)
    while True:
        data = tcp_server.recv(BUF_SIZE)
        if not data:break
        tcp_server.send('[%s] %s'%(time.ctime(),data))
  
tcp_server.close()

위 코드 설명:


1~4행


첫 번째 줄은 Unix 시작 정보 줄, 그 다음 시간 모듈과 소켓 모듈을 가져옵니다.


5~10줄


IP_PORT는 전역 변수입니다. IP 주소와 포트가 선언되어 바인딩() 함수가 이 주소에 바인딩되어 있으며 버퍼 크기가 1K로 설정되어 있습니다. Listen() 함수는 허용되는 최대 연결 수를 나타냅니다.


11~마지막 줄로 이동


이후 서버 루프에 들어가서 연결이 도착할 때까지 수동적으로 기다립니다. 연결이 되면 대화 루프에 들어가 클라이언트가 데이터를 보낼 때까지 기다립니다. 메시지가 비어 있으면 클라이언트가 종료되었음을 의미하며 루프에서 벗어나 다음 연결이 도착할 때까지 기다립니다. 클라이언트 메시지를 받은 후 메시지 앞에 타임스탬프를 추가하고 반환합니다. 루프가 종료되지 않아 서버가 close()를 실행하지 않으므로 마지막 줄은 실행되지 않습니다. close() 함수를 호출하는 것을 잊지 마세요.


클라이언트

#!/usr/bin/env python

# _*_ coding:utf-8 _*_
import socket
  
HOST = '127.0.0.1'
PORT = 8009
BUF_SIZE = 1024
ADDR = (HOST,PORT)
  
client = socket.socket()
client.connect(ADDR)
  
while True:
    data = input(">>> ")
    if not data:break
    client.send(bytes(data,encoding='utf-8'))
    recv_data = client.recv(BUF_SIZE)
    if not recv_data:break
    print(recv_data.decode())
      
client.close()

5~11行

HOST和PORT变量表示服务器的IP地址与端口号。由于演示是在同一台服务器所以IP地址都是127.0.0.1,如果运行在其他服务器上要做相应的修改。端口号要与服务器端完全相同否则无法通信。缓冲区大小还是1K。


客户端套接字在10行创建然后就去连接服务器端


13~21行


客户端也无限循环,客户端的循环在以下两个条件的任意一个发生后就退出:1.用户输入为空的情况或者服务器端响应的消息为空。否则客户端会把用户输入的字符串发送给服务器进行处理,然后接收显示服务器返回来的带有时间戳的字符串。


运行客户端程序与服务端程序


以下是客户端的输入与输出

[root@pythontab]# python client.py 
>>> hello python
[Thu Sep 15 22:29:12 2016] b'hello python'

   


以下是服务端输出

[root@pythontab]# python server.py 
waiting for connection...
...connected from: ('127.0.0.1', 55378)

   

3.socketserver模块

socketserver是标准库中的一个高级别的模块。用于简化实现网络客户端与服务器所需要的大量样板代码。模块中已经实现了一些可以使用的类。


实例1:使用socketserver实现与上面socket()实例一样的功能


服务端程序代码

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socketserver
import time
  
HOST = '127.0.0.1'
PORT = 8009
ADDR = (HOST,PORT)
BUF_SIZE = 1024
  
class Myserver(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            print("...connected from:",self.client_address)
            data = self.request.recv(BUF_SIZE)
            if not data:break
            self.request.send(bytes("%s %s"%(time.ctime(),data)))
  
server = socketserver.ThreadingTCPServer(ADDR,Myserver)
print("waiting for connection...")
server.serve_forever()

   


11~17行


主要的工作在这里。从socketserver的BaseRequestHandler类中派生出一个子类,并重写handle()函数。


在有客户端发进来的消息的时候,handle()函数就会被调用。


19~21行


代码的最后一部分用给定的IP地址和端口加上自定义处理请求的类(Myserver)。然后进入等待客户端请求与处理客户端请求的无限循环中。


客户端程序代码

import socket
HOST = '127.0.0.1'
PORT = 8009
ADDR = (HOST,PORT)
BUF_SIZE = 1024
  
client = socket.socket()
client.connect(ADDR)
  
while True:
    data = input(">>> ")
    if not data:continue
    client.send(bytes(data,encoding='utf-8'))
    recv_data = client.recv(BUF_SIZE)
    if not recv_data:break
    print(recv_data.decode())
  
client.close()

   

执行服务端和客户端代码  


下面是客户端输出

[root@pythontab]# python socketclient.py 
>>> hello python
Thu Sep 15 23:53:31 2016 b'hello python'
>>> hello pythontab
Thu Sep 15 23:53:49 2016 b'hello pythontab'

   


下面是服务端输出

[root@pythontab]# python socketserver.py 
waiting for connection...
...connected from: ('127.0.0.1', 55385)
...connected from: ('127.0.0.1', 55385)
...connected from: ('127.0.0.1', 55385)
...connected from: ('127.0.0.1', 55385)


   


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.