728x90
반응형
- 서버는 클라이언트 접속용 server pipe file을 생성하고 기다린다.
- 클라이언트는 server pipe file을 사용하여 클라이언트 접속을 서버에게 알린다.
- 이때 클라이언트가 생성한 client pipe file 이름을 포함한 클라이언트 정보를 서버에게 알려준다.
- 서버는 client pipe file 을 open하고 클라이언트 목록에 방금 접속한 클라이언트 정보를 추가한다.(클라이언트 이름, client pipe file descriptor)
- 서버는 클라이언트가 접속할 때마다 클라이언트 정보를 화면에 출력한다.
- 서버에 접속한 클라이언트 중 하나가 메시지를 입력하면 서버는 해당 메시지를 모든 클라이언트에게 전달한다.
- 클라이언트는 서버로부터 메시지를 받으면 화면에 해당 메시지를 출력한다
- 파이프는 1:N 통신이 가능하다.
- 클라이언트는 자식 프로세스를 생성해서 서버로 부터 오는 메시지를 받는 역할만 수행하도록 구현할 수 있다. -> 부모 프로세스는 사용자의 입력 메시지를 서버에 전달하는 역할만 수행한다.
- 파이프를 open() 할 때, O_RDONLY나 O_WRONLY 옵션을 주게되면 통신할 프로세스가 사라질 경우 또는 통신하는 상대방이 파이프를 close()할 경우 read()나 write()에서 0이나 -1이 리턴됨. 이를 통해 클라이언트 접속이 끊김을 확인할 수 있음.
* 클라이언트 코드
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#define SERVER_PIPE "/tmp/server_pipe"
#define CLIENT_PIPE "/tmp/client_%d_pipe"
int main() {
int pid = getpid();
char client_pipe[100];
sprintf(client_pipe, CLIENT_PIPE, pid);
mkfifo(client_pipe, 0666);
int server_fd = open(SERVER_PIPE, O_WRONLY);
char buffer[300];
sprintf(buffer, "CONNECT %s", client_pipe);
write(server_fd, buffer, strlen(buffer) + 1);
pid_t child_pid = fork();
if (child_pid == 0) { // Child process
int client_fd = open(client_pipe, O_RDONLY);
while (1) {
ssize_t count = read(client_fd, buffer, sizeof(buffer));
if (count <= 0) { // Connection lost
printf("Connection lost. Exiting.\n");
break;
}
printf("Received message: %s\n", buffer);
}
close(client_fd);
exit(0);
} else { // Parent process
while (1) {
fgets(buffer, sizeof(buffer), stdin);
write(server_fd, buffer, strlen(buffer) + 1);
}
}
close(server_fd);
unlink(client_pipe);
return 0;
}
* 서버 코드
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#define SERVER_PIPE "/tmp/server_pipe"
#define CLIENT_PIPE "/tmp/client_%d_pipe"
typedef struct {
char name[100];
int fd;
} Client;
Client clients[10];
int client_count = 0;
void broadcast_message(const char *message) {
for (int i = 0; i < client_count; i++) {
write(clients[i].fd, message, strlen(message) + 1);
}
}
int main() {
mkfifo(SERVER_PIPE, 0666);
int server_fd = open(SERVER_PIPE, O_RDONLY);
char buffer[300];
while (1) {
read(server_fd, buffer, sizeof(buffer));
if (strncmp("CONNECT", buffer, 7) == 0) {
char client_pipe[100];
sscanf(buffer, "CONNECT %s", client_pipe);
int client_fd = open(client_pipe, O_WRONLY);
Client new_client;
strcpy(new_client.name, client_pipe);
new_client.fd = client_fd;
clients[client_count++] = new_client;
printf("New client connected: %s\n", new_client.name);
} else {
printf("Received message: %s\n", buffer);
broadcast_message(buffer);
}
}
close(server_fd);
unlink(SERVER_PIPE);
return 0;
}
728x90
반응형
'C' 카테고리의 다른 글
[윈도우 소켓프로그래밍] C 학생정보찾기 (0) | 2024.05.27 |
---|---|
[리눅스] 파이프를 사용한 단체방 채팅 서버 만들기(2) (2) | 2023.12.06 |
[C언어] 사용자로부터 양의 정수를 입력받아 주어진 조건에 따라 원래의 수, 뒤집은 수, 그 차이를 출력하는 C 코드 (2) | 2023.10.05 |
[C언어] n개의 정수 입력받고 최대값과 최소값, 2번째 최대값과 최소값 출력하기 (0) | 2023.10.05 |
[C언어] 각 자릿수를 순서대로 영어로 출력하는 프로그램 (0) | 2023.10.05 |