본문 바로가기

개발자/Raspberry Pi3

파이선 소켓 프로그램 1 - 서버와 클라이언트

 

LoRa 통신 구현 중 서버와 클라이언트 데이터 통신을 하게 된다. 클라이언트 데이터를 서버가 받아 저장하고 보여준다. 여기서는 간단한 소켓을 사용하여 데이터 교환의 과정을 보여준다. 

 

클라이언트 코드 client.py

 

#-*- coding:utf-8 -*-
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('메시지를 전송했습니다.')

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

 

서버코드 server.py

 

#-*- coding:utf-8 -*-
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('메시지를 보냈습니다.')

 

 

일단 라즈베리파이에 putty 로 연결한다. putty 연결창을 두 개 열어서 한쪽은 서버에서 파이선 서버 프로그램을 실행한다. 다른 창에서 클라이언트를 실행한다. 

 

서버 결과 화면

서버 프로그램 실행은 $ sudo python server.py

 

pi@raspberrypi:~/bletest $ sudo python server.py
("('127.0.0.1', 45896)", '\xec\x97\x90\xec\x84\x9c \xec\xa0\x91\xec\x86\x8d\xec\x9d\xb4 \xed\x99\x95\xec\x9d\xb8\xeb\x90\x98\xec\x97\x88\xec\x8a\xb5\xeb\x8b\x88\xeb\x8b\xa4.')
('\xeb\xb0\x9b\xec\x9d\x80 \xeb\x8d\xb0\xec\x9d\xb4\xed\x84\xb0 : ', u'I am a client')
메시지를 보냈습니다.
pi@raspberrypi:~/bletest $

 

클라이언트 결과화면 

클라이언트 프로그램 실행은 $ sudo python client.py

 

pi@raspberrypi:~/bletest $ sudo python client.py
연결 확인 됐습니다.
메시지를 전송했습니다.
('\xeb\xb0\x9b\xec\x9d\x80 \xeb\x8d\xb0\xec\x9d\xb4\xed\x84\xb0 : ', u'I am a server.')
pi@raspberrypi:~/bletest $

 

다른 구현 코드를 알아보자.

위의 예는 그대로 적용된다. 여기서는 server2.py client2를 작성한다. 

 

server2.py

 

# -*- coding: utf-8 -*- 
from socket import *
from select import *

HOST = ''
PORT = 10000
BUFSIZE = 1024
ADDR = (HOST, PORT)

# 소켓 생성
serverSocket = socket(AF_INET, SOCK_STREAM)

# 소켓 주소 정보 할당 
serverSocket.bind(ADDR)
print('bind')

# 연결 수신 대기 상태
serverSocket.listen(100)
print('listen')

# 연결 수락
clientSocekt, addr_info = serverSocket.accept()
print('accept')
print('--client information--')
print(clientSocekt)

# 클라이언트로부터 메시지를 가져옴
data = clientSocekt.recv(65535)
print('recieve data : ',data.decode())

# 소켓 종료 
clientSocekt.close()
serverSocket.close()
print('close')

 

1. 우선 소켓을 설정하고, bind()함수를 통해 주소 정보를 할당한다.
2. 이후, listen()함수를 통해 연결 수신 대기 상태로 전환 후 
3. client가 연결할 시 accpet() 함수를 이용하여 연결을 수락한다.
4. 만약 client가 보낸 메시지가 있을 경우, recv(byte크기)를 이용하여 메시지를 가져온다.

 

 

client2.py

 

#! /usr/bin/python
# -*- coding: utf-8 -*-

from socket import *
from select import *
import sys
from time import ctime

HOST = '127.0.0.1'
PORT = 10000
BUFSIZE = 1024
ADDR = (HOST,PORT)

clientSocket = socket(AF_INET, SOCK_STREAM)# 서버에 접속하기 위한 소켓을 생성한다.

try:
	clientSocket.connect(ADDR)# 서버에 접속을 시도한다.
	clientSocket.send('Hello!'.encode())	# 서버에 메시지 전달

except  Exception as e:
    print('%s:%s'%ADDR)
    sys.exit()

print('connect is success')

 

1. 주소와 포트번호를 설정
2. server에 접속하기 위한 client socket을 생성하고
3. connect()함수를 이용하여 서버에 접속을 시도하고, send()함수를 이용해 메시지를 전달한다.

 

실행화면은 아래와 같다. 서버쪽

 

pi@raspberrypi:~/example $ sudo python server2.py
bind
listen
accept
--client information--
<socket._socketobject object at 0x76c0aae8>
('recieve data : ', u'Hello!')
close
pi@raspberrypi:~/example $

 

클라이언트 쪽

 

pi@raspberrypi:~/example $ sudo python client2.py
connect is success
pi@raspberrypi:~/example $

 

자세한 설명은 생략.

 

참고문서

1. https://seolin.tistory.com/97

2. https://m.blog.naver.com/nonamed0000/221259426463

 

 

OSI 7 Layer - https://shlee0882.tistory.com/110

 

팁-OSI 7 Layer 쉽게 외우는 법(이거 외우고 있으면 인생이 편하다.) '이더넷 세파'가 아니라 '피다넷 세파' 이것만 외우면 된다. 여기(http://www.ciokorea.com/news/36536) 보면 무지하게 어렵게 외우는 설명이 있다. 완전 어거지다. 그럼 이더넷 세파 아니라 피다넷 세파는 무엇이냐? 7레이어의 앞 글자만 따서 발음하기 쉽게 만들었다. 이것을 왜 이제서야 공개하는 지 참 내.

 

7계층 – 응용 계층(Application)

6계층 – 표현 계층(Presentation

5계층 – 세션 계층(Session)

4계층 – 전송 계층(Transport)

3계층 – 네트워크 계층(Network)

2계층 – 데이터 링크 계층(Data Link)

1계층 – 물리 계층(Physical)

 

1계층부터 순서대로 적어보면 다음과 같다. Phy-Da-Ne-T-Se-P-A 이렇게 된다. 7계증을 물리, 데이터 네트워크 ~ 하면서 외웠다면 앞단어만 떼서 외우면 금방 외워진다. 평생 잊은 적이 없다. 평생 너를 잊은 적이 없다. -見河-