Client-server example using TCP
server
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
▶ 헤더파일 포함
int main(void)
▶ main 함수 시작
struct sockaddr_in sa;
int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
▶ 소켓 주소 구조체 생성 + 소켓 생성
- socket(): 소켓 생성
- PF_INET: IPv4 프로토콜 사용
- SCOK_STREAM: TCP 사용
- IPPROTP_TCP: TCP 프로토콜
- socket()이 실패하면 -1 반환
if (SocketFD == -1) {
perror("cannot create socket");
exit(EXIT_FAILURE);
}
▶ 소켓 오류 처리
- perror: 에러 출력 함수
- exit(EXIT_FAILURE) == exit(1): 비정상적으로 종료된 프로그램을 에러 로그와 함께 끝냄
memset(&sa, 0, sizeof sa);
sa.sin_family = AF_INET;
sa.sin_port = htons(1100);
sa.sin_addr.s_addr = htonl(INADDR_ANY);
▶ 주소 정보 초기화 및 설정
- memset: 구조체 sa를 0으로 초기화
- sin_family: 주소 체계 설정 (IPv4)
- sin_port: 포트번호 설정 (1100번 포트)
- sin_addr.s_addr: 어떤 IP에서도 접속 허용
if (bind(SocketFD,(struct sockaddr *)&sa, sizeof sa) == -1) {
perror("bind failed");
close(SocketFD);
exit(EXIT_FAILURE);
}
▶ bind: 소켓에 주소 붙이기
- 만든 소켓에 IP 주소 + 포트번호를 붙임
- 실패 시 에러 출력 후 종료
if (listen(SocketFD, 10) == -1) {
perror("listen failed");
close(SocketFD);
exit(EXIT_FAILURE);
}
▶ listen: 연결 대기 시작
- 10: 한 번에 10명까지 대기 가능
for (;;) {
int ConnectFD = accept(SocketFD, NULL, NULL);
if (ConnectFD == -1) {
perror("accept failed");
close(SocketFD);
exit(EXIT_FAILURE);
}
▶ 무한 루프: 계속 연결 받기
- accept: 클라이언트 연결 요청을 수락함
- 연결이 들어올 때까지 기다림 (blocking)
- 새로 연결된 클라이언트는 ConnectFD로 통신하게 됨
char buffer[256]; // 클라이언트로부터 받을 버퍼
memset(buffer, 0, sizeof(buffer));
ssize_t bytesRead = read(ConnectFD, buffer, sizeof(buffer) - 1); // 읽기
if (bytesRead < 0) {
perror("read failed");
}
else {
printf("Received message: %s\n", buffer); // 받은 메시지 출력
const char *response = "Message received.\n";
write(ConnectFD, response, strlen(response)); // 응답 보내기
}
▶ 읽고 씀
if (shutdown(ConnectFD, SHUT_RDWR) == -1) {
perror("shutdown failed");
close(ConnectFD);
close(SocketFD);
exit(EXIT_FAILURE);
}
close(ConnectFD);
}
▶ 연결 종료 및 클린업
- shutdown: 읽기쓰기 모두 종료
- close: 파일 디스크립터(소켓 연결) 닫기
close(SocketFD);
return EXIT_SUCCESS;
▶ 서버 종료 시 메인 소켓도 닫기
client
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
▶ 헤더 포함
int main(void)
▶ main 함수
struct sockaddr_in sa;
int res;
int SocketFD;
▶ 변수 선언
- sa: 접속하려는 서버의 주소 정보
- res: IP 주소 변환 결과 저장
- SocketFD: 클라리언트 소켓 식별자
SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (SocketFD == -1) {
perror("cannot create socket");
exit(EXIT_FAILURE);
}
▶ 소켓 생성 및 실패 처리
memset(&sa, 0, sizeof sa);
sa.sin_family = AF_INET;
sa.sin_port = htons(1100);
res = inet_pton(AF_INET, "192.168.1.3", &sa.sin_addr);
▶ 서버 주소 초기화 및 설정
- &sa.sin_addr: 결과가 저장될 곳
- res가 1이면 성공, 0이면 잘못된 주소, -1이면 오류
if (connect(SocketFD, (struct sockaddr *)&sa, sizeof sa) == -1) {
perror("connect failed");
close(SocketFD);
exit(EXIT_FAILURE);
}
▶ 서버 연결 시도
const char *msg = "Hello, server!";
write(SocketFD, msg, strlen(msg));
char buffer[256];
memset(buffer, 0, sizeof buffer);
read(SocketFD, buffer, sizeof buffer - 1);
printf("Received from server: %s\n", buffer);
▶ 통신 부분
close(SocketFD);
return EXIT_SUCCESS;
▶ 소켓 종료
Client-server example using UDP
server
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
▶ 헤더파일
int main(void)
▶ main 함수
int sock;
struct sockaddr_in sa;
char buffer[1024];
ssize_t recsize;
socklen_t fromlen;
▶ 변수 선언
- sock: 소켓 파일 디스크립터 (UDP 소켓용)
- sa: 클라이언트 주소를 저장할 구조체
- buffer: 받은 데이터를 저장할 공간 (1024 바이트)
- recsize: recvfrom()으로 받은 데이터 크기
- fromlen: 주소 구조체의 크기 (recvfrom()에 필요)
memset(&sa, 0, sizeof sa);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_ANY);
sa.sin_port = htons(7654);
fromlen = sizeof sa;
▶ 주소 정보 설정
- INADDR_ANY: 어떤 IP든 수신하겠다는 의미
- fromlen: recvfrom() 호출에 필요
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (bind(sock, (struct sockaddr *)&sa, sizeof sa) == -1) {
perror("error bind failed");
close(sock);
exit(EXIT_FAILURE);
}
▶ 소켓 생성 및 바인드
- SOCK_DGRAM: UDP 소켓
for (;;) {
recsize = recvfrom(sock, (void*)buffer, sizeof buffer, 0, (struct sockaddr*)&sa, &fromlen);
▶ 무한 루프: 데이터 받기
- recvfrom(): client가 보낸 UDP 패킷을 수신하는 함수 (blocking 함수)
- buffer: 데이터를 저장할 버퍼
- sa: 보낸 클라이언트 주소 정보 저장
- fromlen: 주소 구조체 크기
if (recsize < 0) {
fprintf(stderr, "%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
▶ 오류 처리
- 수신 실패 시 오류 메시지를 strerror(errno)로 출력하고 종료
printf("recsize: %d\n", (int)recsize);
sleep(1);
printf("datagram: %.*s\n", (int)recsize, buffer);
▶ 수신된 데이터 처리
- 받은 데이터의 길이 출력
- 1초 기다렸다가
- 받은 내용을 문자열로 출력
client
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
▶ 헤더파일
int main(void)
▶ main 함수
int sock;
struct sockaddr_in sa;
int bytes_sent;
char buffer[200];
▶ 변수 선언
- sock: 소켓 디스크립터
- sa: 서버 주소 정보를 저장할 구조체
- bytes_sent: 실제로 전송한 바이트 수
- buffer: 보낼 문자열 버
strcpy(buffer, "hello world!");
▶ 보낼 메시지 저장
- buffer에 문자열 저장
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == -1) {
printf("Error Creating Socket");
exit(EXIT_FAILURE);
}
▶ 소켓 생성 및 실패 처리
memset(&sa, 0, sizeof sa);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr("127.0.0.1");
sa.sin_port = htons(7654);
▶ 서버 주소 설정
- inet_addr(): 문자열 IP -> 숫자 IP
- htons: 포트번호를 네트워크 바이트 순서로 변환 (UDP 서버와 같은 포트여야 함)
bytes_sent = sendto(sock, buffer, strlen(buffer), 0,(struct sockaddr*)&sa, sizeof sa);
if (bytes_sent < 0) {
printf("Error sending packet: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
▶ 메시지 전송 및 실패 처리
- sendto() 함수로 UDP 메시지 전송
- sock: UDP 소켓
- buffer: 전송할 데이터
- strlen(buffer): 데이터 길이
- 0: 기본 옵션
- sa: 받을 서버 주소
- 반환값: 전송된 바이트 수
close(sock);
return 0;
▶ 소켓 종료
참고자료
https://en.wikipedia.org/wiki/Berkeley_sockets
Berkeley sockets - Wikipedia
From Wikipedia, the free encyclopedia Inter-process communication API A Berkeley (BSD) socket is an application programming interface (API) for Internet domain sockets and Unix domain sockets, used for inter-process communication (IPC). It is commonly impl
en.wikipedia.org
'CS > 풀스택서비스네트워킹' 카테고리의 다른 글
| Socket Programming in C: Socket API functions (0) | 2025.06.07 |
|---|