파이썬 소켓 프로그래밍: 클라이언트, 서버, 피어 라이브러리
Published: 2023-12-11 09:11:31

이 튜토리얼에서는 파이썬 소켓 프로그래밍과 소켓 API를 사용하여 클라이언트와 서버 간에 데이터를 교환하는 방법을 배웁니다. 나중에 이 튜토리얼에서는 호스팅된 공급자를 사용하여 둘 이상의 파이썬 클라이언트 간에 직접 데이터를 교환하는 방법에 대해 설명합니다. 이 튜토리얼에 사용된 소스 코드는 [깃허브 저장소](https://github.com/PubNubDevelopers/python-socket-demo).

소켓 프로그래밍은 두 개의 소켓(클라이언트 소켓과 서버 소켓)을 연결하여 실시간으로 양방향으로 통신할 수 있도록 합니다. 직접 소켓 연결은 언제든지 데이터를 주고받을 수 있으므로 모든 실시간 애플리케이션에 유용합니다.

파이썬이 소켓 프로그래밍에 적합할까요?
---------------------

네! Python은 클라이언트-서버 애플리케이션을 만드는 데 필요한 소켓, 셀렉트, 비동기 등 많은 필수 모듈이 내장되어 있어 소켓 프로그래밍에 적합합니다.

### Python 소켓은 어떤 용도로 사용되나요?

Python 소켓은 웹 서버, 채팅 애플리케이션, 이메일 클라이언트 등 네트워크를 통해 통신해야 하는 애플리케이션에 사용됩니다. 서버 프로그램은 들어오는 연결을 수신하고 처리하는 반면, 클라이언트는 서버에 연결하여 데이터를 주고받습니다. 파이썬 소켓은 순서대로 패킷을 전송하는 안정적인 프로토콜인 [TCP와](https://www.pubnub.com/guides/tcp-ip/)패킷 손실이 허용되는 애플리케이션을 위한 연결이 필요 없고 가벼운 프로토콜인 [UDP를](https://www.pubnub.com/guides/udp/)모두 지원합니다.

### Python에서 소켓 프로그램을 실행하려면 어떻게 해야 하나요?

다음 가이드는 서로 통신할 수 있는 Python 클라이언트와 서버를 만드는 방법을 안내합니다. 두 프로그램을 별도로 실행해야 합니다:

`파이썬 myServer.py`

`파이썬 myClient.py`

**Python 프로그래밍** 환경 설정
----------------------

다음의 안정적인 버전이 필요합니다. [파이썬 버전 3.x](https://www.python.org/downloads/) 버전이 설치되어 있어야 합니다. Windows 사용자의 경우 경로에 Python을 추가하는 옵션이 있습니다.

또한 이 튜토리얼을 따라하려면 코드 편집기가 필요합니다. [Visual Studio Code는](https://code.visualstudio.com/) Python을 비롯한 여러 언어와 프레임워크를 지원하는 인기 있는 오픈 소스 무료 코드 편집기입니다. VSCode는 코드 완성 및 디버깅에 도움이 되는 Python용 확장 기능도 지원합니다.

Python 소켓 애플리케이션 빌드 및 실행
------------------------

Python을 사용하여 간단한 소켓 애플리케이션을 빌드해 보겠습니다. Python은 네이티브 [소켓 클래스](https://docs.python.org/3/library/socket.html) (소켓 모듈)을 제공하므로 개발자는 외부 라이브러리에 의존할 필요가 없습니다. 먼저 Python 소켓 프로그래밍 클라이언트와 서버를 설정합니다:

![](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jhj/bf547110b07a076c30bac70e1b5a7e9a/python-socket-connection-diagram.png)

### Python 소켓 라이브러리 가져오기

프로젝트 디렉토리에 client.py 파일을 만듭니다. 소켓을 사용하려면 Python 소켓 라이브러리를 가져와서 지정된 IP 주소(이 경우 포트 번호 8080의 localhost)에 연결하는 새 소켓 객체를 만듭니다. 소켓 서버에 대한 새 연결을 만들고, TCP 서버로 데이터를 전송한 다음, 소켓 연결을 닫습니다.

client.py 파일은 다음과 같아야 합니다:

```js
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('0.0.0.0', 8080))
client.send("I am CLIENT\n".encode())
from_server = client.recv(4096)
client.close()
print (from_server.decode())
```

클라이언트로부터 들어오는 연결과 메시지를 수신 대기하려면 소켓 서버가 필요합니다. server.py 파일을 생성하고 다음 내용을 추가합니다:

```js
import socket
serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serv.bind(('0.0.0.0', 8080))
serv.listen(5)
while True:
  conn, addr = serv.accept()
  from_client = ''
  while True:
    data = conn.recv(4096)
    if not data: break
    from_client += data.decode('utf8')
    print (from_client)
    conn.send("I am SERVER\n".encode())
  conn.close()
print ('client disconnected and shutdown')
```

Server.py는 소켓 객체를 포트 8080의 호스트 이름(localhost)에 바인딩하고 새 클라이언트 연결을 계속 수신 대기합니다. 클라이언트가 이 주소에 연결하면 서버는 연결을 수락하고 모든 데이터를 읽습니다. 클라이언트에서 데이터를 성공적으로 읽으면 서버는 데이터 응답을 제공하며, 이 시점에서 클라이언트는 연결을 종료합니다.

### Python 소켓 프로그래밍 테스트

이를 직접 테스트하려면 두 개의 터미널 창을 동시에 엽니다. 한 창에서 다음을 실행합니다:

```js
python3 server.py
```

두 번째 창에서 실행합니다:

```js
python3 client.py
```

서버가 계속 실행되고 클라이언트를 실행하고 새 출력을 추가할 때마다 새 연결이 설정되는 것을 확인할 수 있습니다.

클라이언트는 서버에 "나는 클라이언트입니다"라는 문자열을 전송하고 응답을 기다립니다. 서버는 클라이언트의 메시지를 읽고 터미널에 출력한 후 클라이언트에 응답을 다시 보냅니다.

![](https://images.ctfassets.net/3prze68gbwl1/6Y2HAKVJOGza5CUHcJyg8k/2480975a9fecd808b273cdf834ecb65b/python_sockets.png)

PubNub을 사용한 파이썬의 소켓 프로그래밍
-------------------------

지금까지 이 튜토리얼에서는 서버와 클라이언트 간에 메시지를 주고받는 방법을 다루었지만 Python 클라이언트 간에 직접 통신해야 하는 경우에는 어떻게 해야 할까요?

두 개 이상의 클라이언트 기기 간에 직접 데이터를 전송하는 것은 기기 수가 증가함에 따라 많은 확장 및 보안 고려 사항에 직면하기 때문에 까다롭습니다. 클라이언트-서버 아키텍처는 클라이언트 간 통신을 조정하고 관리하는 데 사용됩니다. 웹 서버가 없거나 애플리케이션의 요구 사항을 충족하기 위한 서버 확장이 걱정된다면 다음과 같은 호스팅된 실시간 커뮤니케이션 솔루션을 선택해야 합니다. [PubNub](https://www.pubnub.com/). PubNub은 전 세계적으로 분산되고 확장 가능한 클라우드 플랫폼이므로 서버 배포 및 유지 관리에 대해 걱정할 필요가 없습니다. PubNub의 크로스 플랫폼 SDK는 다음을 포함합니다. [Python](https://www.pubnub.com/docs/sdks/python)을 포함한 PubNub의 크로스 플랫폼 SDK는 사용자를 식별하고 구독한 클라이언트만 수신할 수 있는 특정 채널로 메시지를 보낼 수 있습니다.

### 클라이언트 대 클라이언트 Python 소켓 프로그래밍

그렇다면 앞서 소개한 간단한 앱을 PubNub로 작성하여 두 클라이언트 간에 직접 메시지를 교환하려면 어떻게 해야 할까요? PubNub는 '게시' 및 '구독' 아키텍처(pub/sub)를 사용하여 엔드포인트 간에 양방향 메시지를 보내고 받지만, 그 이면에는 여전히 소켓을 사용한다는 점을 이해하는 것이 중요합니다. PubNub을 사용하면 Python 네트워크 프로그래밍의 세부 사항에 대해 걱정할 필요 없이 소켓 통신의 이점을 누릴 수 있으며 운영 체제에 관계없이 클라이언트 간의 연결을 항상 유지할 수 있습니다.

PubNub을 프로젝트에 통합하려면 터미널에 pip와 함께 PubNub 패키지를 설치하면 다음과 같이 사용할 수 있습니다. [PubNub Python SDK](https://www.pubnub.com/docs/sdks/python) 를 사용하고 PubNub 인프라와 통신할 수 있습니다.

```js
pip3 install 'pubnub>=7.1.0'
```

PubNub 네트워크에 연결하고 통신하려면 두 개의 클라이언트를 만들어야 합니다. pn\_client\_1.py 파일을 생성하고 다음 코드를 추가합니다:

```js
from pubnub.callbacks import SubscribeCallback
from pubnub.enums import PNStatusCategory
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
import time
import os
pnconfig = PNConfiguration()
userId = os.path.basename(__file__)
pnconfig.publish_key = 'demo'
pnconfig.subscribe_key = 'demo'
pnconfig.user_id = userId
pnconfig.ssl = True
pubnub = PubNub(pnconfig)
def my_publish_callback(envelope, status):
  # Check whether request successfully completed or not
  if not status.is_error():
    pass
class MySubscribeCallback(SubscribeCallback):
  def presence(self, pubnub, presence):
    pass
  def status(self, pubnub, status):
    pass
  def message(self, pubnub, message):
    if message.publisher == userId : return
    print ("from device " + message.publisher + ": " + message.message)
pubnub.add_listener(MySubscribeCallback())
pubnub.subscribe().channels("chan-1").execute()
## publish a message
while True:
  msg = input("")
  if msg == 'exit': os._exit(1)
  pubnub.publish().channel("chan-1").message(str(msg)).pn_async(my_publish_callback)
```

pn\_client\_2.py 파일을 생성하고 pn\_client\_1.py에 사용한 것과 동일한 코드를 추가합니다.

위의 코드는 '데모' 키를 사용하지만 사용자 정의된 사용자 정의 [PubNub 키](https://admin.pubnub.com/#/register) 를 무료로 얻을 수 있습니다.

두 개의 다른 터미널 창에서 pn\_client\_1.py와 pn\_client\_2.py를 동시에 실행합니다.

```js
python3 pn_client_1.py
```

```js
python3 pn_client_2.py
```

각 클라이언트는 PubNub 네트워크에 대한 연결을 초기화하고 'chan-1' 채널에 새 메시지가 게시될 때마다 이를 수신하도록 구독합니다. 이것은 Python에서 TCP 소켓을 통해 데이터를 전송하는 것으로 생각할 수 있으며, 뒤에서 PubNub은 사용자를 위해 소켓을 생성 및 관리하고 메시지를 수신하는 모든 클라이언트에 메시지를 라우팅합니다. 원격 클라이언트가 메시지를 수신하면 수신된 메시지가 명령줄에 표시됩니다.

![](https://images.ctfassets.net/3prze68gbwl1/7BRsG0oVaACcE34x7eC0yC/475d6a894f0bc535bc70d213a9e8c189/python_pubnub.png)

이것이 전부입니다!

파이썬에서 소켓의 대안은 무엇인가요?
--------------------

PubNub로 개발하는 방법에 대한 자세한 내용은 다양한 [튜토리얼](https://www.pubnub.com/tutorials/) 과 [데모](https://www.pubnub.com/demos/)또는 [PubNub 인터랙티브 투어](https://www.pubnub.com/tour/introduction/) 를 통해 플랫폼이 애플리케이션에 실시간 상호작용을 제공하는 방법을 알아보세요. PubNub은 Linux, Unix, Windows뿐만 아니라 TCP 및 UDP 데이터그램 통신을 지원합니다.

전문가가 작성한 웹소켓 관련 문서와 가이드를 비롯하여 실시간 메시징에 대한 광범위한 리소스 모음을 보유하고 있습니다. 다음은 몇 가지 유용한 링크입니다.

-   [웹소켓이란 무엇인가요?](https://www.pubnub.com/guides/what-are-websockets-and-when-should-you-use-them/)
    
-   [PubNub 리소스](https://www.pubnub.com/resources)
    
-   [PubNub 블로그](https://www.pubnub.com/blog/)
    

PubNub이 어떤 도움을 줄 수 있나요?
=======================

이 문서는 원래 [PubNub.com에](https://pubnub.com/blog/socket-programming-in-python-client-server-p2p/) 게시되었습니다.

저희 플랫폼은 개발자가 웹 앱, 모바일 앱, IoT 기기를 위한 실시간 인터랙티브를 구축, 제공, 관리할 수 있도록 지원합니다.

저희 플랫폼의 기반은 업계에서 가장 크고 확장성이 뛰어난 실시간 에지 메시징 네트워크입니다. 전 세계 15개 이상의 PoP가 8억 명의 월간 활성 사용자를 지원하고 99.999%의 안정성을 제공하므로 중단, 동시 접속자 수 제한, 트래픽 급증으로 인한 지연 시간 문제를 걱정할 필요가 없습니다.

PubNub 체험하기
-----------

[라이브 투어를](https://www.pubnub.com/tour/introduction/) 통해 5분 이내에 모든 PubNub 기반 앱의 필수 개념을 이해하세요.

설정하기
----

PubNub [계정에](https://admin.pubnub.com/signup/) 가입하여 PubNub 키에 무료로 즉시 액세스하세요.

시작하기
----

사용 사례나 [SDK에](https://www.pubnub.com/docs) 관계없이 [PubNub 문서를](https://www.pubnub.com/docs) 통해 바로 시작하고 실행할 수 있습니다.