안 쓰던 블로그

[파이썬] 소켓 프로그래밍-1대1 채팅 시스템 본문

언어/파이썬

[파이썬] 소켓 프로그래밍-1대1 채팅 시스템

proqk 2020. 9. 6. 18:30
반응형

소켓

애플리케이션 계층에서 프랜스포트 계층을 조작하기 위한 인터페이스

그 둘 계층 사이에 존재한다

 

작동 방식은 A컴에도 소켓이 있고 B컴에도 소켓이 있어서

A컴이 소켓한테 B한테 메시지 좀 보내주라고 하면 소켓이 전달

B컴이 소켓한테 메시지 온 거 있는지 확인 좀 해 달라고 하면 소켓이 확인

이런 식으로 소켓이 우체통 같은 역할로 작동한다

 

 

기본 서버 소켓 세팅

from socket import *

serverSock = socket(AF_INET, SOCK_STREAM) #소켓 생성
serverSock.bind(('', 8080)) #bind-서버에서만 필요. 튜플 형식이라 (())이고 ip, port가 한 쌍
serverSock.listen(1) #1개의 동시접속만 허용

clientSock, addr = serverSock.accept() #누가 접속할 때까지 대기

bind에서 ''은 모든 인터페이스에게 연결 허용이라는 뜻이라

8080번 포트에서 모든 인터페이스에게 연결을 허용했다는 의미이다

 

 

기본 클라이언트 소켓 세팅

from socket import *

clientSock = socket(AF_INET, SOCK_STREAM) #소켓 생성
clientSock.connect(('127.0.0.1', 8080)) #서버에 접속하기 위한 connect((호스트주소, 포트))

클라이언트에서는 connect만 하면 된다

connect도 튜플이라서 (())로 묶어줬고 지금은 자기 자신한테 8080번 포트로 연결하라는 의미

 


한 번 메시지를 주고 받는 코드

서버

from socket import *

serverSock = socket(AF_INET, SOCK_STREAM)
serverSock.bind(('', 8080))
serverSock.listen(1)

connectionSock, addr = serverSock.accept()

print(str(addr),'에서 접속했습니다')

data = connectionSock.recv(1024)
print('받은 데이터 : ', data.decode('utf-8'))

connectionSock.send('I am a server.'.encode('utf-8'))
print('I am a server 메시지를 보냈습니다.')

 

클라이언트

from socket import *

clientSock = socket(AF_INET, SOCK_STREAM)
clientSock.connect(('127.0.0.1', 8080))

print('연결에 성공했습니다.')
clientSock.send('I am a client'.encode('utf-8'))

print('I am a client 메시지를 전송했습니다.')

data = clientSock.recv(1024)
print('받은 데이터 : ', data.decode('utf-8'))

 

서버부터 실행하고 클라이언트 실행

결과

 

하지만 이런 방법으로는 무조건 서버가 먼저 시작해야 한다

송수신 순서 상관없이 동시에 메시지를 보내기 위해서 쓰레드 를 사용한다


쓰레드

프로세스 내부에서 병렬 처리를 하기 위해 프로세스 소스코드 내부에서 특정 함수의 복제본을 생성하는 것

원래 한 번에 하나씩 처리해야 할 일을 동시에 여러 개를 처리할 수 있게 해 준다

 

sendd = threading.Thread(target=send, args=(connectionSock,))
receivee = threading.Thread(target=receive, args=(connectionSock,))

쓰레드는 Thread로 생성한다

target은 쓰레드가 실행할 함수를 전달한다(위에서는 send함수)

args는 함수에 전달할 인자값이고 튜플 형태이다

유의할 점은 args에 값이 하나 뿐이면 튜플이 아닌 var로 인식되므로 인자가 하나라면 뒤에 ,를 찍어주어야 한다

 

1:1채팅 프로그램

서버

from socket import *
import threading
import time


def send(sock):
    while True:
        sendData = input('>>>')
        sock.send(sendData.encode('utf-8'))


def receive(sock):
    while True:
        recvData = sock.recv(1024)
        print('상대방 :', recvData.decode('utf-8'))


port = 8081

serverSock = socket(AF_INET, SOCK_STREAM)
serverSock.bind(('', port))
serverSock.listen(1)

print('%d번 포트로 접속 대기중...'%port)

connectionSock, addr = serverSock.accept()

print(str(addr), '에서 접속되었습니다.')

sender = threading.Thread(target=send, args=(connectionSock,)) #send함수를 인자를 넣어 쓰레드 생성
receiver = threading.Thread(target=receive, args=(connectionSock,)) #receive함수를 인자를 넣어 쓰레드 생성

sender.start()
receiver.start()

while True: #프로그램을 계속 실행한다
    time.sleep(1) #1초 쉰다
    pass

 

클라이언트

from socket import *
import threading
import time


def send(sock):
    while True:
        sendData = input('>>>')
        sock.send(sendData.encode('utf-8'))


def receive(sock):
    while True:
        recvData = sock.recv(1024)
        print('상대방 :', recvData.decode('utf-8'))


port = 8081

clientSock = socket(AF_INET, SOCK_STREAM)
clientSock.connect(('127.0.0.1', port))

print('접속 완료')

sender = threading.Thread(target=send, args=(clientSock,))
receiver = threading.Thread(target=receive, args=(clientSock,))

sender.start()
receiver.start()

while True:
    time.sleep(1)
    pass

 

결과

 

 

 

참고

seolin.tistory.com/97

반응형
Comments