반응형
카테고리 | 게시글 작성 날짜 | 게시글 최근 수정 날짜 | 작성자 |
Network | 2021.10.01. 05:30 | 2022.04.06. 23:02 | Dev.Yang |
Unix Domain Socket은 IPC socket (Inter-Process Communication Socket) 이라고도 불리며, TCP (전송 제어 프로토콜, Transmission Control Protocol)의 소켓과 동일한 구조로 데이타를 주고 받을 수 있는 Local File
형식 기반의 소켓입니다. 즉, 동일한 시스템 내에서 파일을 통하여 실행되는 프로세스들 사이의 양방향 데이터 교환을 허용하는 프로세스 간 통신 메커니즘
이다.
- Unix Domain Socket은
localhost
의 각 Process 통신이 되므로 속도가 매우 빠르며 메모리 사용량이 적다는 장점이 있습니다. - TCP (전송 제어 프로토콜, Transmission Control Protocol) 프로토콜을 사용하는 네트워크 작업과 달리 UDS (Unix Domain Socke)는 Routing 작업을 수행하지 않습니다.
- UDS (Unix Domain Socke) 사용하여 통신 작업을 수행할 경우에는
Local File
파일 단위로 통신 작업이 이루어지기에 파일에 접근권한을 제어하여 간단하게 서버와 클라이언트 단위로 프로세스 통신을 제어할 수 있습니다.
/*
* Copyright (c) 2023 Universal-SystemKit. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <sys/un.h>
#include <sys/socket.h>
#define SK_SOCKET_SUCCESS 0
#define SK_SOCKET_FAIL -1
#define SK_SOCKET_EMPTY_PADDING 0
#define SK_CONNECT_REQUEST_QUEUE_MAX 5
#pragma mark - Typedef
typedef void(^SKCompletionHandler)(NSString * message);
@interface SKUnixSocket : NSObject
@property (nonatomic, copy, readwrite) SKCompletionHandler handler;
- (const int) listen: (NSString *) socketPath;
- (const bool) send: (NSString *) socketPath
: (NSString *) base64String;
@end
@implementation SKUnixSocket
#pragma mark - Private Instance Method
- (const int) makeUnixSocket {
const int result = socket(AF_UNIX, SOCK_STREAM, 0);
if (result < SK_SOCKET_SUCCESS) {
NSLog(@"[SKUnixSocket] Failed to create a Unix Domain Socket");
return SK_SOCKET_FAIL;
}
NSLog(@"[SKUnixSocket] Successfully created a Unix Domain Socket: %d", result);
return result;
}
- (const struct sockaddr_un) makeUnixSockAddr: (NSString *) path {
// sockaddr_un 구조체를 생성하고 초기화 합니다.
struct sockaddr_un sockAddr;
memset(&sockAddr, SK_SOCKET_EMPTY_PADDING, sizeof sockAddr);
sockAddr.sun_family = AF_UNIX;
strcpy(sockAddr.sun_path, path.UTF8String);
return sockAddr;
}
- (void) handleClient: (const int) clientSocket {
char buffer[256];
memset(&buffer, SK_SOCKET_EMPTY_PADDING, sizeof buffer);
while (true) {
const ssize_t length = read(clientSocket, buffer, 255);
if (length < 0) {
//
close(clientSocket);
break;
}
//
NSString * result = [NSString stringWithUTF8String: buffer];
self.handler(result);
}
}
- (void) acceptClients: (const int) serverSocket {
@synchronized (self) {
while (true) {
const int clientSocket = accept(serverSocket, NULL, NULL);
if (clientSocket < SK_SOCKET_SUCCESS) {
NSLog(@"Error: Accept failed.");
continue;
}
const dispatch_queue_t dispatch = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(dispatch, ^{
[self handleClient: clientSocket];
});
}
}
}
#pragma mark - Public Instance Method
- (const int) listen: (NSString *) socketPath {
@autoreleasepool {
// Unix Domain Socket 기반의 TCP 소켓을 생성합니다.
const int serverSocket = [self makeUnixSocket];
// 정상적으로 UDS (Unix Domain Socket) 생성 여부를 확인합니다.
if (serverSocket == SK_SOCKET_FAIL) { return false; }
// sockaddr_un 생성하고 초기화 합니다.
const struct sockaddr_un serverAddr = [self makeUnixSockAddr: socketPath];
//
unlink(socketPath.UTF8String);
//
const int result = bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof serverAddr);
if (result < SK_SOCKET_SUCCESS) {
NSLog(@"Error: Binding failed.");
return false;
}
//
listen(serverSocket, SK_CONNECT_REQUEST_QUEUE_MAX);
//
[self acceptClients: serverSocket];
// 생성 한 서버 소켓을 종료합니다.
return close(serverSocket);
}
}
- (const bool) send: (NSString *) socketPath
: (NSString *) message {
@autoreleasepool {
// Unix Domain Socket 기반의 TCP 소켓을 생성합니다.
const int clientSocket = [self makeUnixSocket];
// 정상적으로 UDS (Unix Domain Socket) 생성 여부를 확인합니다.
if (clientSocket == SK_SOCKET_FAIL) { return false; }
const struct sockaddr_un serverAddr = [self makeUnixSockAddr: socketPath];
const int result = connect(clientSocket, (struct sockaddr *) &serverAddr, sizeof serverAddr);
if (result < SK_SOCKET_SUCCESS) {
NSLog(@"[SKUnixSocket] Failed to connect to the server");
return false;
}
// 서버에 데이터를 전송합니다.
const ssize_t length = write(clientSocket, message.UTF8String, message.length);
NSLog(@"[SKUnixSocket] Data has been transmitted to the server: %zd Bytes", length);
// 생성 한 클라이언트 소켓을 종료합니다.
close(clientSocket);
return length == message.length;
}
}
@end
🛠 Unix Domain Socket Type
- SOCK_STREAM (Compare to TCP): for a stream-oriented socket.
- SOCK_DGRAM (Compare to UDP): for a datagram-oriented socket that preserves message boundaries (as on most UNIX implementations, UNIX domain datagram sockets are always reliable and don't reorder datagrams).
- SOCK_SEQPACKET (Compare to SCTP): for a sequenced-packet socket that is connection-oriented, preserves message boundaries, and delivers messages in the order that they were sent.
🛠 Unix Domain Socket 관련 명령어
L
→ lsof: 실행 중인 파일과 프로세스의 정보를 출력하는 명령어입니다. 시스템 전체의 UDS (Unix Domain Socket) 목록을 확인하기 위해서는-U
옵션을 사용합니다.L
→ ls: 디렉터리 목록을 출력하는 명령어입니다. 디렉터리 내부의 파일들에 대한 UDS (Unix Domain Socket) 사용여부를 확인하고자 하는 경우에는-luh
옵션을 사용합니다. 아래의 예시와 같이 디렉터리나 파일의 권한을 나타내는 부분에s
문자가 표시 된 파일은 UDS (Unix Domain Socket) 통신을 수행하고 있는 소켓 파일을 나타냅니다.
📣 REFERENCE
반응형
'#컴퓨터 과학 [Computer Science] > 네트워크 (Network)' 카테고리의 다른 글
[네트워크] TCP/IP (Internet Protocol Suite) 계층 (0) | 2024.08.27 |
---|---|
[🔒 보안] CBC (Cipher block chaining) (0) | 2023.09.11 |
[🔒 보안] ECB (Electronic CodeBook) (0) | 2023.09.11 |
[네트워크] 네트워크 (Network) 용어 정리 (0) | 2019.08.22 |
댓글