TCP 소켓 통신
네트워크에 대해 설명하는 글이 아니므로, 간단히 설명해보겠습니다.
소켓 통신은 방법에 따라 TCP, UDP로 나뉩니다.
TCP는 그 유명한 3 - Way Handshaking으로 통신을 시작하는데,
먼저 송신자(Client)가 연결을 맺기 위한 요청(syn)을 보내고,
수신자(Server)가 수락하는 SYN+ ACK 패킷을 보냅니다.
이후, 송신자(Client)는 확인했다는 의미로 ACK 패킷을 보내 연결하는데,
이러한 동작방식 때문에 TCP를 연결 지향적(Connection-Oriented) 프로토콜이라 합니다.
비연결 지향적(Connection-Less)인 UDP에 비해 신뢰성을 제공하나,
복잡한 연결과정 때문에 속도면에서는 UDP에 비해 느립니다.
이번엔 이런 TCP 프로토콜을 사용해 WiFi에 접속하여 두 아두이노 보드간에 소켓을 주고받아 보겠습니다.
(* 클라이언트 / 서버 둘 중 하나가 아두이노 위의 프로그램이 아니여도 됩니다.)
저는 와이파이 기능이 내장되어 있는 Wemos D1 mini 두 개를 사용하였습니다.
클라이언트측
#include <ESP8266WiFi.h>
#include <stdio.h>
// 와이파이명
const char* ssid = "와이파이 이름";
const char* password = "와이파이 비밀번호";
int num = 0;
void setup() {
Serial.begin(115200);
delay(10);
int n = WiFi.scanNetworks();
Serial.println("Scan Done");
if(n == 0) {
Serial.println("no networks found");
} else {
Serial.print(n);
Serial.println(" networks found");
for(int i = 0; i<n; i++) {
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.print(")");
Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*");
delay(10);
}
}
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println("connection Start");
}
void loop() {
WiFiClient client;
if(!client.connect("0.0.0.0",5000)) { // 서버 아이피, 포트번호 입력
Serial.println("connection failed"); // 서버 접속에 실패
delay(500);
}
// 서버 소켓 보내기
client.write(num++);
client.write("\n");
delay(1000);
}
setup에서는 와이파이 세팅을,
loop 에서는 서버로 소켓을 보내는 작업을 합니다.
포트번호는 5000번을 사용하였습니다.
서버측
#include <ESP8266WiFi.h>
#include <SPI.h>
#include <Ethernet.h>
// 와이파이명
const char* ssid = "와이파이 이름";
const char* password = "와이파이 비밀번호";
WiFiServer server(5000);
void setup() {
Serial.begin(115200);
delay(1000);
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi . . .");
}
Serial.println("Connected to WiFi");
// start the server
server.begin();
Serial.println("Server started");
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
}
void loop() {
WiFiClient client = server.available();
if(client) {
Serial.println("Client Connected");
String string = "";
//모든 글자 읽어오기
while(client.connected()) {
if(client.available()) {
char c = client.read();
string += c;
}
}
Serial.println(string);
}
client.stop();
Serial.println("Client Disconnected");
delay(1000);
}
서버 역시 5000번 포트로 서버를 연 모습입니다.
setup에서는 와이파이 세팅을,
loop에서는 소켓을 전달받아 Serial로 출력합니다.
서버 / 클라이언트간 TCP 통신이 정상적으로 작동한 모습이네요.
모듈 두개간 서로 통신할 일이 생겼는데,
선이 너무 거추장스러워 블루투스로 무선 통신을 해볼까? 했다가,
와이파이 칩이 내장된 d1 mini 를 발견하여 TCP를 사용해 소켓 통신을 하였습니다.
시행착오가 좀 많았지만 잘 작동되는 걸 보니 좋네요.
'IoT > Arduino' 카테고리의 다른 글
[아두이노] RESTful API로 JSON 담아서 POST 요청 보내기 (3) | 2023.04.27 |
---|---|
[아두이노] Wemos D1 mini로 WiFi(와이파이) 연결 (0) | 2023.03.29 |
[아두이노] Wemos D1 mini 세팅 (0) | 2023.03.29 |