๐ ์์ผ ํต์ ์ด๋?
์ฐ์ ์์ผ์ ๋ ๊ฐ์ ์ปดํจํฐ(์๋ํฌ์ธํธ)๋ฅผ ์ฐ๊ฒฐํ๋ ํต๋ก๋ฅผ ์๋ฏธํ๋ฉฐ ๋ ๊ฐ์ ์ปดํจํฐ๋ ์ด๋ฅผ ํตํด ๋คํธ์ํฌ๊ฐ ํ์ฑ๋๋ค.
์ ์ํ์์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ํต์ ์ ํ๋ ๊ฒ์ ์์ผ ํต์ ์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
์์ผ ํต์ ์ ์ฐ๊ฒฐ ์งํฅํ ํต์ ์ธ TCP์ ๋น์ฐ๊ฒฐ ์งํฅ ํต์ ์ธ UDP๊ฐ ์๋ค.
๐ ์์ผ ํต์ ๊ณผ์
์ฌ์ฉ์๊ฐ ๊ตฌ๊ธ์ ๋ฌด์ธ๊ฐ๋ฅผ ๊ฒ์ํ ๋๋ฅผ ์์๋ก ๋ค๋ฉด ํต์ ๊ณผ์ ์ ๋ค์์ ๊ฐ๋ค.
์๋ฒ ์ธก (Google ์๋ฒ PC)
- socket() ํจ์๋ฅผ ํตํด ์์ผ์ ์์ฑ
- bind() ํจ์๋ฅผ ํตํด ์์ผ์ IP ์ฃผ์์ ํฌํธ ๋ฒํธ๋ฅผ ํ ๋นํ์ฌ ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ์ฐ๊ฒฐํ ์ ์๊ฒ ํจ
- listen() ํจ์๋ฅผ ํตํด ํด๋ผ์ด์ธํธ์ ์ฐ๊ฒฐ ์์ฒญ์ ๊ธฐ๋ค๋ฆผ
- accept() ํจ์๋ฅผ ํตํด ํด๋ผ์ด์ธํธ์ ์ฐ๊ฒฐ ์์ฒญ์ ์๋ฝํ๊ณ , ๋ค๋ฅธ ํด๋ผ์ด์ธํธ์ ์์ผ๊ณผ ํต์ ํ ์ ์๋
์๋ก์ด ์์ผ์ ์์ฑ
ํด๋ผ์ด์ธํธ ์ธก (์น ๋ธ๋ผ์ฐ์ - ํฌ๋กฌ)
- socket() ํจ์๋ฅผ ํตํด ์์ผ์ ์์ฑ
(โป ํ๋์ ์ปดํจํฐ์ ์ฌ๋ฌ ์์ผ์ด ์กด์ฌํ ๋ ๊ตฌ๋ถ์ง๊ธฐ ์ํด ํฌํธ ๋ฒํธ๋ฅผ ๋ค๋ฅด๊ฒ ํ์ฌ ์์ฑํ๊ณ
์๋ฒ ์์ผ ์์๋ ํฌํธ ๋ฒํธ๋ฅผ ํ์ธ ํ ๊ตฌ๋ถํ์ฌ ๋ฐ์ธ๋ฉ ํจ) - connect() ํจ์๋ฅผ ํตํด ์๋ฒ ์์ผ์ ์ฐ๊ฒฐ์ ์๋
- send() ํจ์๋ฅผ ํตํด ์๋ฒ์ ๋ฐ์ดํฐ(์ ๋ ฅํ ๊ฒ์์ด)๋ฅผ ์ ์ก
- recv() ํจ์๋ฅผ ํตํด ์๋ฒ๋ก๋ถํฐ ๋ฐ์ดํฐ(๊ฒ์ ๊ฒฐ๊ณผ)๋ฅผ ์์
- close ํจ์๋ฅผ ํตํด ํต์ ์ด ๋๋๋ฉด ์์ผ์ ๋ซ์
์์ผ ํต์ ์ ๊ตฌ์ฒด์ ์ธ ๋คํธ์ํฌ ๋ด์ฉ(e.g. TCP, UDP)์ ์๋ ๋งํฌ์ ๋ฐ๋ก ์ ๋ฆฌํ์์ต๋๋ค.
๐ ์ค์ต ๋ชฉํ
- ์์ผ ํต์ ์ ์ด์ฉํ ํ์ผ ์ ์ก ํ๋ก๊ทธ๋จ ์์ฑ
- ์๋ฒ
ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ์๋ฒ๋ฅผ ๊ตฌ๋์ํฌ ๋ ์์ฑ ๋๋ ์ด๊ฑฐํ ํ์ผ์ ์ ์ฅํจ - ํด๋ผ์ด์ธํธ
์ ํํ ํ์ผ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด ์๋ฒ์ ์ ์ก
- ์๋ฒ
- make ํ์ผ๋ก ๋น๋
- server, client ํ๋ก๊ทธ๋จ ์คํ
- ์๋ฒ์ ์ ๋ฌํ ๋ฐ์ดํฐ ์ ์ฅ๋จ ํ์ธ
๐ ์ค์ต ๊ฒฐ๊ณผ
Ubuntu ํ๊ฒฝ์์ ํ์ผ ์์ฑํ์์ผ๋ฉฐ ๋ฐ๋ก git์ ์ ๋ก๋ ํ์ง ์์์ต๋๋ค.
์์ผ ํต์ ์ ์ด์ฉํ ํ์ผ ์ ์ก ํ๋ก๊ทธ๋จ ์์ฑ
1. client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void error_handling(char *message);
int main(int argc, char* argv[])
{
int sock; // ์์ผ ํ์ผ ์๋ณ์
struct sockaddr_in serv_addr; // ์๋ฒ ์์ผ ์ฃผ์ ๊ตฌ์กฐ์ฒด
char message[100]; // ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๋ฒํผ
int str_len; // ์ฝ๊ฑฐ๋ ์ด ๋ฐ์ดํฐ์ ํฌ๊ธฐ
int rfd; // ํ์ผ ์ฝ๊ธฐ๋ฅผ ์ํ ํ์ผ ์๋ณ์
// ๋งค๊ฐ๋ณ์๊ฐ ๋ถ์กฑํ ๊ฒฝ์ฐ ์ฌ์ฉ ๋ฐฉ๋ฒ ์ถ๋ ฅ ํ ์ข
๋ฃ
if(argc != 4)
{
printf("Usage : %s <IP> <port>\n", argv[0]);
exit(1);
}
// ํ์ผ์ ์ฝ๊ธฐ ๋ชจ๋๋ก ์ด๊ธฐ
rfd = open(argv[3], O_RDONLY);
// ํ์ผ ์ด๊ธฐ ์คํจ ์ ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ ํ ์ข
๋ฃ
if(rfd < 0)
{
perror("open()");
error_handling("read() error");
}
// TCP ์์ผ ์์ฑ
sock = socket(PF_INET, SOCK_STREAM, 0);
// ์์ผ ์์ฑ ์คํจ ์ ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ ํ ์ข
๋ฃ
if(sock == -1)
error_handling("socket() error");
// ์๋ฒ ์์ผ ์ฃผ์ ๊ตฌ์กฐ์ฒด ์ด๊ธฐํ
memset(&serv_addr, 0, sizeof(serv_addr));
// ์๋ฒ ์ฃผ์ ์ ๋ณด ์ค์
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
serv_addr.sin_port = htons(atoi(argv[2]));
// ์๋ฒ์ ์ฐ๊ฒฐ
if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
error_handling("connect() error!");
do
{
// ํ์ผ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์์ ๋ฒํผ์ ์ ์ฅ
str_len = read(rfd, message, sizeof(message));
// ์ฝ์ ๋ฐ์ดํฐ๊ฐ ์์ ๊ฒฝ์ฐ ๋ฐ๋ณต๋ฌธ ํ์ถ
if(str_len == 0)
break;
// ์ฝ์ ๋ฐ์ดํฐ๋ฅผ ์๋ฒ ์์ผ์ผ๋ก ์ ์ก
write(sock, message, str_len);
} while(1);
// ํด๋ผ์ด์ธํธ ์์ผ ๋ซ์ ํ ์ข
๋ฃ
close(sock);
return 0;
}
// ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ ํ ํ๋ก๊ทธ๋จ ์ข
๋ฃ
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
2. server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void error_handling(char *message);
int main(int argc, char *argv[])
{
int serv_sock; // ์๋ฒ ์์ผ ํ์ผ ์๋ณ์
int clnt_sock; // ํด๋ผ์ด์ธํธ ์์ผ ํ์ผ ์๋ณ์
struct sockaddr_in serv_addr; // ์๋ฒ ์์ผ ์ฃผ์ ๊ตฌ์กฐ์ฒด
struct sockaddr_in clnt_addr; // ํด๋ผ์ด์ธํธ ์์ผ ์ฃผ์ ๊ตฌ์กฐ์ฒด
socklen_t clnt_addr_size; // ํด๋ผ์ด์ธํธ ์ฃผ์ ๊ตฌ์กฐ์ฒด์ ํฌ๊ธฐ
char message[100]; // ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๋ฒํผ
int str_len; // ์ฝ๊ฑฐ๋ ์ด ๋ฐ์ดํฐ์ ํฌ๊ธฐ
int wfd; // ํ์ผ ์ฐ๊ธฐ๋ฅผ ์ํ ํ์ผ ์๋ณ์
// ๋ช
๋ น์ด ๋งค๊ฐ๋ณ์๊ฐ ๋ถ์กฑํ ๊ฒฝ์ฐ ์ฌ์ฉ ๋ฐฉ๋ฒ ์ถ๋ ฅ ํ ์ข
๋ฃ
if(argc != 3)
{
printf("Usage : %s <port> <file>\n", argv[0]);
exit(1);
}
// ํ์ผ์ ์ฐ๊ธฐ ๋ชจ๋๋ก ์ด๊ธฐ (ํ์ผ์ด ์์ผ๋ฉด ์์ฑ, ์ด๋ฏธ ์์ผ๋ฉด ๋ด์ฉ์ ๋ชจ๋ ์ง์ฐ๊ณ ์๋ก ์์ฑ)
wfd = open(argv[2], O_CREAT | O_TRUNC | O_WRONLY, 0644);
// ํ์ผ ์ด๊ธฐ ์คํจ ์ ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ ํ ์ข
๋ฃ
if(wfd < 0)
{
perror("error");
}
// TCP ์์ผ ์์ฑ
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
// ์์ผ ์์ฑ ์คํจ ์ ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ ํ ์ข
๋ฃ
if(serv_sock == -1)
error_handling("socket() error");
// ์๋ฒ ์์ผ ์ฃผ์ ๊ตฌ์กฐ์ฒด ์ด๊ธฐํ
memset(&serv_addr, 0, sizeof(serv_addr));
// ์๋ฒ ์ฃผ์ ์ ๋ณด ์ค์
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(atoi(argv[1]));
// ์์ผ์ ์ฃผ์ ํ ๋น
if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1)
error_handling("bind() error");
// ์ฐ๊ฒฐ ์์ฒญ ๋๊ธฐ ์ํ ์ง์
if(listen(serv_sock, 5) == -1)
error_handling("listen() error");
// ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ์ฐ๊ฒฐ ์์ฒญ์ด ์ฌ ๋๊น์ง ๋๊ธฐ
clnt_addr_size = sizeof(clnt_addr);
clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);
// ํด๋ผ์ด์ธํธ ์์ผ ์ฐ๊ฒฐ ์คํจ ์ ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ ํ ์ข
๋ฃ
if(clnt_sock == -1)
error_handling("accept() error");
do
{
// ํด๋ผ์ด์ธํธ ์์ผ์ผ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ด
str_len = read(clnt_sock, message, sizeof(message));
// ์ฝ์ ๋ฐ์ดํฐ๊ฐ ์์ ๊ฒฝ์ฐ ๋ฐ๋ณต๋ฌธ ํ์ถ
if(str_len <= 0)
break;
// ์ฝ์ ๋ฐ์ดํฐ๋ฅผ ํ์ผ์ ์ฐ๊ธฐ
write(wfd, message, str_len);
} while(1);
// ํด๋ผ์ด์ธํธ ์์ผ๊ณผ ์๋ฒ ์์ผ ๋ซ์ ํ ํ๋ก๊ทธ๋จ ์ข
๋ฃ
close(clnt_sock);
close(serv_sock);
return 0;
}
// ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ ํ ํ๋ก๊ทธ๋จ ์ข
๋ฃ
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
make ํ์ผ๋ก ๋น๋
1. makefile
# Makefile ๋ณ์ ์ ์
CC := gcc # ์ปดํ์ผ๋ฌ ๋ณ์๋ฅผ 'gcc'๋ก ์ค์
# ์ปดํ์ผํ ๊ฐ์ฒด ํ์ผ๋ค์ ๋ชฉ๋ก์ ์ ์
OBJECTS_CLIENT = client.o
OBJECTS_SERVER = server.o
TARGET_CLIENT = client # ๋น๋ํ ์คํ ํ์ผ์ ์ด๋ฆ์ 'client'๋ก ์ค์
TARGET_SERVER = server # ๋น๋ํ ์คํ ํ์ผ์ ์ด๋ฆ์ 'server'๋ก ์ค์
# ๋น๋ ๊ท์น ์ ์
$(TARGET_CLIENT): $(OBJECTS_CLIENT)
$(CC) -o $@ $(OBJECTS_CLIENT) # ์ปดํ์ผ๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ์คํ ํ์ผ ์์ฑ
$(TARGET_SERVER): $(OBJECTS_SERVER)
$(CC) -o $@ $(OBJECTS_SERVER) # ์ปดํ์ผ๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ์คํ ํ์ผ ์์ฑ
# ์ผ๋ฐ์ ์ธ ๊ท์น ์ ์: ๊ฐ .c ํ์ผ์ ํด๋นํ๋ .o ํ์ผ๋ก ์ปดํ์ผ๋จ
%.o: %.c
$(CC) -c -o $@ $< # ์ปดํ์ผ๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ .c ํ์ผ์ .o ํ์ผ๋ก ๋ณํ
# 'clean' ๊ท์น ์ ์: ๋น๋๋ ํ์ผ๋ค ์ ๊ฑฐ
clean:
rm -f *.o $(TARGET_CLIENT) $(TARGET_SERVER) # ํ์ฌ ๋๋ ํ ๋ฆฌ์ .o ํ์ผ ๋ฐ ์คํ ํ์ผ ์ ๊ฑฐ
2. ๋น๋ ๊ฒฐ๊ณผ
๋น๋ ๊ฒฐ๊ณผ server.c ํ์ผ์ ๋น๋๋์ง ์๊ณ client.c ํ์ผ๋ง ๋น๋ ๋์ด
server.c ํ์ผ์ ์๋ ๋ช
๋ น์ด๋ฅผ ํตํด์ ๋น๋ ํ์๋ค.
sudo gcc -o server server.c
server, client ํ๋ก๊ทธ๋จ ์คํ
1. server ํ๋ก๊ทธ๋จ ์คํ
์ฌ์ฉํ port ๋ฒํธ + ํด๋ผ์ด์ธํธ๋ก ๋ฐ์ ๋ฐ์ดํฐ ์ ์ฅ์ฉ ํ์ผ ์ ํ
(โป ํด๋น ๊ฒฝ๋ก์ ํ์ผ์ด ์กด์ฌํ ๊ฒฝ์ฐ ์ด๊ฑฐํ๊ณ ์์ผ๋ฉด ๋น ํ์ผ ์์ฑ)
2. ์๋ฒ์ ์ ๋ฌํ ๋ฐ์ดํฐ ํ์ผ ์์ฑ
3. client ํ๋ก๊ทธ๋จ ์คํ
์๋ฒ ip ์ฃผ์ + ์ฌ์ฉํ port ๋ฒํธ + ์๋ฒ์ ๋ฐ์ดํฐ ์ ๋ฌ์ฉ ํ์ผ ์ ํ
์๋ฒ์ ์ ๋ฌํ ๋ฐ์ดํฐ ์ ์ฅ๋จ ํ์ธ
๋ฐ์ดํฐ ์ ์ฅ์ฉ ํ์ผ์ ๋ฐ์ดํฐ๊ฐ ์กด์ฌํ ๊ฒฝ์ฐ ์ญ์ ๋๊ณ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฐ์ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋จ ํ์ธ
'embedded' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[ubuntu] MySQL ํ์ฉ IoT ๋ฐ์ดํฐ ์ ์ด ์ค์ต (0) | 2023.11.23 |
---|---|
[ubuntu] ์์ผ ํต์ ์ฑํ ์๋ฒ (0) | 2023.11.23 |
[protocol] bxCAN ์ด๋ก ์ ๋ฆฌ (0) | 2023.10.29 |
[device] CAN Gateway ์ด๋ก ์ ๋ฆฌ (0) | 2023.10.26 |
[protocol] CAN ํต์ ์ด๋ก ์ ๋ฆฌ (0) | 2023.10.14 |