본문 바로가기
language/python

[Python] 소켓프로그래밍으로 1:1 채팅 구현

by sseddi 2020. 9. 8.
728x90

먼저 소켓은 어플리케이션 계층과 전송 계층 간을 이어주는 인터페이스이다.

프로그램 개발 시 어플리케이션 계층에 한정되어서 개발을 하는데 이 어플리케이션 계층에서도 전송 계층을 조작할 수 있는 방법이 소켓이라고 하는 인터페이스를 사용하는 방법이다.

1:1 채팅을 구현하기 위해서 소켓 프로그래밍을 사용할 건데

소켓 세팅 과정이 있다.

 

( //주의 // 아래 내용부터는 구글링해서 찾은 코드를 해석한내용이다. )

 

먼저 <<서버 소켓>>을 만들어야 한다.

socket을 임포트 해주고 

socket 객체를 생성할 수 있다. 이때 인자를 입력하는데 첫 번째 인자는 AF(Address Family) 이고 두번째는 소켓 타입이다.

소켓은 인터넷이 아닌 통신도 고려되서 만들어졌는데,, 지금은 인터넷 네트워크만을 주로 사용하기 때문에 AF_INET이라는 어드레스 패밀리 한가지만이 사용된다고 해도 괜찮다고 한다.

 

소켓 타입은 크게 연결지향형 소켓과 비 연결지향형 소켓이 있다.

 

SOCK_STREAM을 사용하면 연결지향형 소켓이 생성되는데 그 특징으로는

>>중간에 데이터가 소멸되지 않고 목적지로 전송

>>전송 순서대로 데이터가 수신

>>전송되는 데이터의 경계가 존재하지 않음

>> 소켓 대 소켓의 연결은 반드시 1:1이어야 함

 

반면 SOCK_DGRAM을 사용하면 비 연결지향형 소켓이 생성된다. 그 특징으로는

>>전송된 순서 상관없이 가장 빠른 전송 지향

>>전송된 데이터는 손실의 우려가 있고, 파손의 우려가 있음

>>전송되는 데이터의 경계가 존재함

>> 한번에 전송할 수 있는 데이터의 크기가 제한됨

 

전송되는 데이터의 경계와 관련한 것은 잘 모르겠지만, 1:1 채팅 프로그램을 구현하는데에는 연결지향형 소켓이 더 알맞는 것 같아 SOCK_STREAM을 사용하려고 한다.

 

위에 port 변수를 미리 선언해 포트 번호를 지정해주었다. (뒤에 접속 대기중 문구에 쓰려고)

socket을 생성한 후에는 bind해주어야 한다. 

그렇지만 이는 서버 소켓을 만들 때 필요한거고 클라이언트 소켓에서는 필요없다고 한다.

 

bind는 생성된 소켓 번호와 실제 어드레스 패밀리를 연결해주는 것이고,

소켓명.bind.()로 사용하는데 bind 함수 안에 튜플을 입력해주어야 한다.

 

튜플은 불변한 순서가 있는 객체의 집합으로 리스트와 비슷하지만 한번 생기면 그 값을 변경할 수 없다.

괄호 안에 데이터가 나열되어 있는 형식인데

여기서는 (IP, port)로 한 쌍으로 구성된 튜플을 넣어주면 된다. 

이게 곧 어드레스 패밀리로 연결이 되는 것이다.

이때 IP 부분에 빈 문자열을 넣어주는데 그 의미는 모든 인터페이스와 연결하고 싶다는 것과 같다.

 

그 다음으로는 상대방의 접속을 기다리는 단계로 넘어가겠다는 listen이 필요하다.

이것도 bind와 마찬가지로 서버 소켓에서만 사용하는데 listen()에서 괄호 안에 숫자가 쓰여지는데 1이 쓰여지면 한 개의 접속만을 허용하고 인자를 입력하지 않으면 파이썬이 자의적으로 임의의 숫자를 listen 한다.

그래서 코드에는 괄호안에 1을 써주었다.

 

accept()는 누가 소켓에 접속해서 연결되었을 때 결과값이 리턴되는 함수이다.

소켓에 접속해서 연결될 때까지 프로그램은 이 부분에서 멈춰있는다.

accept()가 실행되면 리턴값으로 새로운 소켓과 상대방의 AF를 전달한다.

그리고 이후 서버에 접속한 상대방과 데이터를 주고 받기 위해선 connectionSock 이라는 소켓을 이용하면 된다.

 

마지막 부분은 메시지를 보내고 받는 부분이다.

connectionSock을 이용해 데이터를 주고 받는데; encode()를 사용해 문자열을 byte로 반환해준다.

 

메시지를 보낼 때는 send()를 사용한다.

그리고 파이썬 내부에서의 문자열을 전송계층에다가 그대로 보낼 수 없고 인코딩을 해서 보내야 에러가 뜨지않는다.

 

메시지를 받을 때는 recv()를 사용하는데 recv()를 실행하면 소켓에 메시지가 실제로 수신될 때까지 파이썬이 대기한다.

인자로는 수신할 바이트의 크기를 지정할 수 있는데 1024를 적어서 1024 바이트만큼 가져올 수 있다고 지정해주었다.

메시지를 받을 때는 보낼 때와는 다르게 decode()를 사용해 데이터를 디코딩 해주어야 한다.

 

채팅 프로그램이므로 메시지를 여러번 주고 받을 수 있도록 프로그램 강제 종료 전까지 계속 실행되도록 while True문을 작성했다.

 

다음은 <<클라이언트 소켓>> 차례이다.

 

서버 소켓과 같이 먼저 socket을 임포트 해주고

 

서버 소켓과 같은 포트번호를 사용한다.

그리고 socket 생성까지는 같으나

 

다른 것이 다 빠지고 connect가 추가되었다.

여기에도 호스트 주소와 포트번호로 구성된 튜플이 요구되어 적어준다.

127.0.0.1은 자기 자신을 의미하는 호스트 주소이고, port는 앞의 서버 소켓과 같은 8080을 사용한다.

AF는 자기 자신에게 8080번 포트로 연결하라고 하는 의미이다.

메시지 주고 받는 부분은 서버 소켓 부분과 비슷해 설명 생략하려고 한다.

 

실행화면

서버 소켓 실행 시(서버 화면)
클라이언트 소켓 실행 시(클라이언트 화면/서버 화면)
서버 소켓에서 대화
클라이언트 소켓에서 대화

 

단점) 

서버->클라이언트->서버=>클라이언트 이렇게 전송 순서가 정해져있다.

한번 보내면 순서가 넘어가서 보내지 못한다

 

더 공부해서 스스로 단점을 극복할 수 있는 채팅 프로그램 구현해보고 싶다.

 

참고)

slideplayer.com/slide/10740698/

 

Socket Program Training 10/27/2010. What is a Socket ? An interface between an application process and transport layer (TCP or U

3 TCP Client Socket ( ) Connect ( ) send ( ) Close ( ) send ( ) Read ( ) Accept ( ) recv ( ) Listen ( ) Bind ( ) Socket ( ) recv ( ) Close ( ) Waiting for the requests from client Build a connection Data (request) Data (reply) Deal with the request TCP Ser

slideplayer.com

seolin.tistory.com/97?category=762768

 

파이썬 소켓 프로그래밍 - 1. 간단한 채팅 프로그램 구현(1)

작년에 컴퓨터 네트워크 강의시간에 파이썬 소켓 프로그래밍 강의를 받은 적이 있습니다. 간단한 웹 서버 구축과 채팅 프로그램 구축 둘 중 하나를 택하는 거였는데, 네트워크 개념을 다시 복습

seolin.tistory.com

hannom.tistory.com/27

 

[TCP/IP 소켓]소켓의 타입과 프로토콜의 설정

∙프로토콜(Protocol) 프로토콜이란 컴퓨터 상호간의 대화에 필요한 통신규약이라고 볼 수 있다. 쉽게 말해서 서로 데이터를 주고 받기 위해서 정의해 놓은 약속을 뜻한다. ∙소켓의 생성 #include in

hannom.tistory.com

 

728x90

댓글