Python - 소켓 네트워크 프로그램 개발 찍어먹기

2 분 소요

소켓 네트워크 프로그래밍 찍어먹기

소켓을 통한 메시지 전달 (기본형태)

#서버 프로그램
import socket, time

host = '192.168.103.55' #서버 주소
port = 3333             #서버 포트번호

#서버소켓오픈(대문을 열어둠): socket.AF_INET:주소종류(ip) 
#socket.SOCK_STREAM:통신종류.(UDP, TCP). socket.SOCK_STREAM는 TCP통신
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#여러번 ip,port를 바인드하면 에러나므로 그걸 방지하기 위한 설정
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

#server socket에 ip와 port 붙여줌(바인드)
server_socket.bind((host, port))

#클라이언트 접속 준비 완료
server_socket.listen()

print('echo server start')

#accept(): 클라이언트 접속 기다리며 대기. 
#클라이언트가 접속하면 서버와 클라이언트가 1:1통신할 소켓(빨대)와, 
#접속한 클라이언트의 주소를 반환
client_soc, addr = server_socket.accept()

print('connected client addr:', addr)

#recv(메시지크기): 소켓에서 크기만큼 읽음. 
#소켓에 읽을 데이터 없으면 생길때까지 기다림
data = client_soc.recv(100) 
msg = data.decode()#읽은 데이터 디코딩
print('recv msg:', msg)
client_soc.sendall(msg.encode(encoding='utf-8'))#클라이언트에 에코 메시지 전송

time.sleep(5)
server_socket.close()
#클라이언트 프로그램
import socket

server_ip = '192.168.103.55'#연결할 서버 ip
server_port = 3333          #연결할 서버 port

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect((server_ip, server_port))#서버 accept()에 연결요청

msg = input('msg:')
socket.sendall(msg.encode(encoding='utf-8'))#서버로 메시지 전송

#서버가 에코로 되돌려보낸 메시지 받음
data = socket.recv(100)
msg = data.decode()#읽은 데이터 디코딩
print('echo msg:', msg)

socket.close()

메시지를 여러번 주고 받을 수 있도록 수정

클라이언트가 ‘/end’ 입력하면 서버, 클라이언트 모두 종료

#서버 프로그램
import socket, time

host = '192.168.103.55' #서버 주소
port = 3333             #서버 포트번호

#서버소켓오픈(대문을 열어둠): socket.AF_INET:주소종류(ip) 
#socket.SOCK_STREAM:통신종류.(UDP, TCP). socket.SOCK_STREAM는 TCP통신
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#여러번 ip,port를 바인드하면 에러나므로 그걸 방지하기 위한 설정
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

#server socket에 ip와 port 붙여줌(바인드)
server_socket.bind((host, port))

#클라이언트 접속 준비 완료
server_socket.listen()

print('echo server start')

client_soc, addr = server_socket.accept()

print('connected client addr:', addr)

while True:
    data = client_soc.recv(100) 
    msg = data.decode()#읽은 데이터 디코딩
    print('recv msg:', msg)
    client_soc.sendall(msg.encode(encoding='utf-8'))#클라이언트에 에코 메시지 전송
    if msg=='/end':
        break

time.sleep(5)
print('서버 종료')
server_socket.close()
#클라이언트 프로그램
import socket

server_ip = '192.168.103.55'
server_port = 3333

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect((server_ip, server_port))

while True:
    msg = input('msg:')
    socket.sendall(msg.encode(encoding='utf-8'))

    #서버가 에코로 되돌려보낸 메시지 받음
    data = socket.recv(100)
    msg = data.decode()#읽은 데이터 디코딩
    print('echo msg:', msg)
    if msg=='/end':
        break

socket.close()

여러 클라이언트가 에코 서버에 접속할 수 있도록 서버수정

#서버 프로그램
import socket, time, threading

def f1(soc):
    while True:
        data = soc.recv(100) 
        msg = data.decode()#읽은 데이터 디코딩
        print('recv msg:', msg)
        soc.sendall(msg.encode(encoding='utf-8'))#클라이언트에 에코 메시지 전송
        if msg=='/end':
            break

def main():
    host = '192.168.103.55' #서버 주소
    port = 3333             #서버 포트번호

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind((host, port))
    server_socket.listen()
    print('echo server start')
    
    while True:
        client_soc, addr = server_socket.accept()#접속대기
        th = threading.Thread(target=f1, args=(client_soc,))
        th.start()
        print('connected client addr:', addr)
    

    time.sleep(5)
    print('서버 종료')
    server_socket.close()
    
main()

멀티스레딩을 사용해서 채팅프로그램 만들기

#채팅서버
import socket, threading
members=[]

def sendMsgAll(msg):#인자로 받은 메시지를 채팅방에 있는 모든 사람에 전송
    print('sendMsgAll:', msg)
    for i in members:
        i.sendall(msg.encode(encoding='utf-8'))
            
#쓰레드 작업. 클라이언트 하나당 하나 생성됨. 소켓으로 연결된 클라이언트가 전송한 메시지를 받아서 전체에 전달
def f1(p, soc):
    id = 'member'+str(p)
    msg = id+'님이 입장하셨습니다'
    sendMsgAll(msg)
    
    while True:
        msg = soc.recv(100)
        msg = msg.decode()
        if msg=='/end':
            msg = id+'님이 퇴장하셨습니다'
            soc.sendall(msg.encode(encoding='utf-8'))
            members.remove(soc)#채팅방에서 제거
            sendMsgAll(msg)
            break
        msg = id+': '+msg
        sendMsgAll(msg)
    
def main():
    host = '192.168.103.55' #서버 주소
    port = 3334             #서버 포트번호

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind((host, port))
    server_socket.listen()
    print('chatting server start')
    
    while True:
        client_soc, addr = server_socket.accept()#클라이언트 기다림
        members.append(client_soc)
        print('connected client addr:', addr)
        #쓰레드 생성
        th = threading.Thread(target=f1, args=(addr[1], client_soc))
        th.start()
        
    server_socket.close()
    
main()
#채팅 클라이언트
#쓰레드로 작업을 분리
#th1: 서버가 전송한 메시지 받아서 출력
#th2: 메시지를 키보드 입력받아서 서버로 전송. /end 입력하면 종료

import socket, threading

soc = None


def sendMsg():
    while True:
        msg = input('msg:')
        soc.sendall(msg.encode(encoding='utf-8'))
        if msg == '/end':
            break


def recvMsg():
    while True:
        data = soc.recv(100)
        msg = data.decode()  # 읽은 데이터 디코딩
        print(msg)
        if msg == '/end':
            break

    soc.close()


def main():
    global soc
    server_ip = '192.168.103.55'
    server_port = 3334

    soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    soc.connect((server_ip, server_port))

    th1 = threading.Thread(target=sendMsg)
    th1.start()

    th2 = threading.Thread(target=recvMsg)
    th2.start()


main()

댓글남기기