서버 통신
회사에서 Unity와 데이터 주고 받을 때 Docker container통신, 그리고 IP 카메라와 데이터 주고 받을 때 사용했는데
매번 할 때마다 왜 오류나고 난리인지..ㅠㅠ
서버 통신
소켓 (socket)과 포트(port)
소켓은 소프트웨어로 작성된 다른 컴퓨터와 네트워크를 통해 데이터를 송수신하기 위한 창구 역할을 하는 통신 접속점
- 소켓을 구성한다는 것은 이웃과 연락할 수 있는 *전화기 **를 설치하는 것과 비슷한 개념
데이터를 주고 받을 때 위의 그림에서 주황색으로 칠해진 socket 이라는 개념을 통해 데이터를 주고 받을 수 있음
포트(port) 는 네트워크 상에서 통신하기 위해서 호스트 내부적으로 프로세스가 할당받아야 하는 고유한 숫자
하나의 소켓은 여러개의 포트를 할당 받을 수 있음
- 포트는 설치된 전화기로 연락하기 위해 필요한 특정한 이웃에게 연결되어 있는 번호
소켓 (Socket)
파이썬으로 TCP(Transmission Control Protocol) 서버/클라이언트 프로그램을 작성할 때 사용하는 표준 라이브러리
socket 의 TCP에 대한 소켓 API 호출 순서와 데이터 플로우
-
소켓과 포트를 bind 즉, 연결
-
listen -> 어떤 client 들이 접속해 있는지 듣고 있음
-
clinet가 서버과 연결을 하기 위해 connect라는 것을 보냄
-
서버가 accept 하게 되면 연결이 이루어짐
-
client가 어떤 데이터나 signal을 send
-
서버가 receive를 통해 값을 받아 처리를 함
-
처리된 결과를 다시 client에게 보내줌
-
client가 close를 하면 signal을 받아 close를 함
socket
을 이용한 TCP 통신 Python 예제
Server
import socket
# 접속할 서버 주소
## hostname 또는 ip address를 사용가능
HOST = '127.0.0.1'
# 클라이언트 접속을 대기하는 포트 번호, 서버가 사용하게 될 Port 번호 (비어있는 port 사용 가능)
PORT = 9999
# 소켓 객체를 생성
# IPv4, 소켓 타입으로 TCP 사용
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 포트 사용중이라 연결할 수 없다는 WinError 10048 에러 해결를 위한 코드
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# bind 함수는 소켓을 특정 네트워크 인터페이스와 포트 번호에 연결
server_socket.bind((HOST, PORT))
# 클라이언트 들이 접속을 요청을 하는지 듣고 클라이언트의 접속 허용
server_socket.listen()
print('서버 실행')
# accept 함수에서 대기하다가 클라이언트가 접속하면 클라이언트의 소켓정보와 주소값을 받아서 연결 진행
client_socket, addr = server_socket.accept()
print('접속한 클라이언트 주소')
print('Connected by', addr)
while True:
# 클라이언트가 보낸 메시지를 수신하기 위해 대기하고 안의 숫자는 받을 문자열의 길이
data = client_socket.recv(1024)
# 빈 문자열을 수신하면 루프를 중지
if not data:
break
# 수신받은 데이터 출력
print('Received from', addr, data.decode())
# 받은 문자열을 다시 클라이언트로 전송(에코)
client_socket.sendall(data)
# 소켓을 닫기
client_socket.close()
server_socket.close()
Client
import socket
# 클라이언트가 아닌 서버의 주소 필요
HOST = '127.0.0.1'
# 서버에서 지정해 놓은 포트 번호
PORT = 9999
# 소켓 객체를 생성
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 지정한 HOST와 PORT를 사용하여 서버에 접속
client_socket.connect((HOST, PORT))
# 데이터 전송
client_socket.sendall('안녕!'.encode())
# 데이터 수신
data = client_socket.recv(1024)
print('Received', repr(data.decode()))
# 소켓 닫기
client_socket.close()