Uknow's Lab.
article thumbnail

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를 사용해 소켓 통신을 하였습니다.

 

시행착오가 좀 많았지만 잘 작동되는 걸 보니 좋네요.

profile

Uknow's Lab.

@유노 Uknow

인생은 Byte와 Double 사이 Char다. 아무말이나 해봤습니다.