유닉스 도메인 소켓은 같은 시스템에서 통신이 일어나므로 TCP/IP 프로토콜을 직접 이용할 필요가 없다. 따라서 유닉스 도메인 소켓에서 사용하는 소켓 주소 구조체의 항목도 IP 주소가 아닌 경로명을 지정하도록 되어 있다.
#include <sys/socket.h> // 소켓 프로그래밍을 위한 기본적인 함수나 상수를 정의
#include <sys/un.h> // 로컬 UNIX 도메인 소켓 프로그래밍을 위한 함수나 상수를 정의
#include <unistd.h> // 유닉스와 리눅스에서 사용하는 다양한 함수 호출들을 정의
#include <stdlib.h> // C 표준 라이브러리에서 제공하는 일반적인 유틸리티 함수들을 정의
#include <stdio.h> // C 표준 라이브러리에서 제공하는 입출력 관련 함수들을 정의
#include <string.h> //C 표준 라이브러리에서 제공하는 문자열 관련 함수들을 정의
#define SOCKET_NAME "hbsocket" // 소켓의 이름
int main() {
char buf[256];
struct sockaar_un ser, cli;
int sd, nsd, len, clen;
if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { // UNIX 도메인 소켓 | TCP 소켓 생성
perror("socket");
exit(1);
}
memset((char *)&ser, 0, sizeof(stuct sockaddr_un)); // 소켓 주소 구조체를 초기화
set.sun_family = AF_UNIX; // 소켓 주소 구조체에서 소켓 패밀리를 AF_UNIX로 지정
strcpy(ser.sun_path, SOCKET_NAME); // 소켓 경로명을 지정
len = sizeof(ser.sun_family) + strlen(ser.sun_path);
if (bind(sd, (struct sockaddr *)&ser, len)) { // bind() 함수로 소켓 기술자를 소켓 주소 구조체와 연결해 이름을 등록
perror("bind");
exit(1);
}
if (listen(sd, 5) < 0 { // listen() 함수를 호출하여 통신할 준비가 되었음을 나타냄
perror("listen");
exit(1);
}
printf("Waiting ... \n");
if ((nsd = accept(sd, (struct sockaddr *)&cli, &clen)) == -1) {
perror("accept");
exit(1);
} // accept() 함수를 호출하여 클라이언트의 접속 요청을 수락하고 새로운 소켓 기술자를 생성해 nsd에 저장. 클라리언트와는 nsd를 통해 통신을 하게 된다.
if (recv(nsd, buf, sizeof(buf), 0) == -1) { // 클라이언트가 보낸 메시지를 recv() 함수로 받아서 출력
perror("recv");
exit(1);
}
printf("Received Message: %s\n", buf);
close(nsd);
close(sd); // 출력을 완료했으므로 소켓을 닫는다.
}
#include <sys/socket.h> // 소켓 프로그래밍을 위한 기본적인 함수나 상수를 정의
#include <sys/un.h> // 로컬 UNIX 도메인 소켓 프로그래밍을 위한 함수나 상수를 정의
#include <unistd.h> // 유닉스와 리눅스에서 사용하는 다양한 함수 호출들을 정의
#include <stdlib.h> // C 표준 라이브러리에서 제공하는 일반적인 유틸리티 함수들을 정의
#include <stdio.h> // C 표준 라이브러리에서 제공하는 입출력 관련 함수들을 정의
#include <string.h> //C 표준 라이브러리에서 제공하는 문자열 관련 함수들을 정의
#define SOCKET_NAME "hbsocket" // 소켓의 이름
int main() {
int sd, len;
char buf[256];
struct sockaddr_un ser;
if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { // UNIX 도메인 소켓 | TCP 소켓 생성
perror("socket");
exit(1);
}
memset((char *)&ser, '\0', sizeof(ser)); // 소켓 구조체 초기화
ser.sun_family = AF_UNIX; // 소켓 패밀리를 AF_UNIX로 지정함
strcpy(ser.sun_path, SOCKET_NAME);
len = sizeof(ser.sun_family) + strlen(ser.sun_path);
if (connect(sd, (struct sockaddr *)&ser, len) < 0) { // 소켓 주소 구조체에 지정한 서버로 connect() 함수를 사용해 연결 요청
perror("bind");
exit(1);
}
strcpy(buf, "Unix Domain Socket Test Message"); // 서버에 전송할 메시지 지정
if (send(sd, buf, sizeof(buf), 0) == -1) { // 서버로 메시지 전송
perror("send");
exit(1);
}
close(sd);
}
이 코드를 실행하여 클라이언트가 보낸 Unix Domain Socket Test Message를 서버에서 받아 출력했음을 알 수 있다. (서버를 먼저 실행 시켜야 함)
한 번 실행하고 다시 실행하면 bind: Address already in use 라는 오류가 뜨니
unlink(SOCKET_NAME);
을 실행하여 파일을 지우도록 해야 함
인터넷 소켓은 서로 다른 시스템 사이에 통신하므로 TCP/IP 프로토콜을 직접 이용한다.
따라서 소켓 주소 구조체의 항목에 IP 주소와 포트 번호를 지정해야 한다.
#include <sys/socket.h> // 소켓 프로그래밍을 위한 기본적인 함수나 상수를 정의
#include <sys/un.h> // UNIX 도메인 소켓 프로그래밍을 위한 함수나 상수를 정의
#include <unistd.h> // 유닉스, 리눅스에서 사용하는 다양한 함수 호출들을 정의
#include <arpa/inet.h> // 네트워크 프로그래밍에 사용되는 함수들과 상수들을 정의
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define PORTNUM 9000 // 포트 번호 지정
int main() {
char buf[256];
struct sockaddr_in sin, cli;
int sd, ns, clientlen = sizeof(cli);
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { // 인터넷 | TCP 소켓 생성
perror("socket");
exit(1);
}
memset((char *)&sin, '\0', sizeof(sin)); // 소켓 구조체 초기화
sin.sin_family = AF_INET;
sin.sin_port = htons(PORTNUM);
sin.sin_addr.s_addr = inet_addr("192.168.147.129"); // 서버의 IP 주소 (192.168.147.129)를 지정하고 포트 번호는 9000으로 지정해 소켓 주소 구조체를 생성
if (bind(sd, (struct sockaddr *)&sin, sizeof(sin))) { // bind() 함수로 소켓 이름을 정함
perror("bind");
exit(1);
}
if (listen(sd, 5)) { // listen() 함수를 호출해 접속 요청을 받을 준비를 마쳤음을 알림
perror("listen");
exit(1);
}
if ((ns = accept(sd, (struct sockaddr *)&cli, &clientlen)) == -1 ) {
perror("accept");
exit(1);
} // accept() 함수로 클라이언트 요청 수락
sprintf("buf, "Your IP address is %s", inet_ntoa(cli.sin_addr)); // 접속한 클라이언트의 IP 주소를 읽어 메시지를 작성
if (send(ns, buf, strlen(buf) + 1, 0) == -1) { // send() 함수로 메시지를 전송
perror("send");
exit(1);
}
close(ns);
close(sd); // 사용을 마친 소켓을 모두 닫는다.
}
#include <sys/un.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define PORTNUM 9000 // 포트 번호 지정
int main() {
int sd;
char buf[256];
struct sockaddr_in sin;
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) { // 인터넷 | TCP 소켓 생성
perror("socket");
exit(1);
}
memset((char *)&sin, '\0', sizeof(sin)); // 구조체 초기화
sin.sin_family = AF_INET;
sin.sin_port = htons(PORTNUM);
sin.sin_addr.s_addr = inet_addr("192.168.147.129"); // IP와 포트 번호 지정
if (connect(sd, (struct sockaddr *)&sin, sizeof(sin))) { // connect() 함수를 사용해 서버에 연결 요청
perror("connect");
exit(1);
}
if (recv(sd, buf, sizeof(buf), 0) == -1) { // 연결되면 서버에서 오는 메시지를 받음
perror("recv");
exit(1);
}
close(sd); // 사용을 마친 소켓을 닫음
printf("From Server : %s\n", buf); // 서버에서 온 메시지 출력
}
서버에서 보낸 메시지를 클라이언트에서 출력함을 할 수 있음 ( 서버 프로그램을 먼저 실행시켜야 한다. )