c언어 소켓 통신 예제 (멀티 스레드, 멀티 프로세스)
멀티 스레드와 멀티 프로세스의 차이점을 설명한 글입니다.
요약하자면, 가장 큰 차이는 멀티스레드 방식은 공유 메모리를 갖고, 멀티프로세스 방식은 별도 메모리를 갖는듯..
내용을 확인 하신 후 상황에 맞는 소켓을 작성 하시기 바랍니다.
https://you9010.tistory.com/136
예제는 해외 사이트에서 가져왔으나, client 수 제한이 없거나 좀비프로세스 발생을 원치 않는다면 아래 URL 에서도 깔끔한 소스를 보실 수 있습니다.
https://velog.io/@jyongk/Multi-Process-Server-Multi-Thread-Server
멀티 스레드 방식
socket_server.c
#include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #include <arpa/inet.h> #include <fcntl.h> // for open #include <unistd.h> // for close #include <pthread.h>
char client_message[2000]; char buffer[1024]; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void * socketThread(void *arg) { int newSocket = *((int *)arg); recv(newSocket , client_message , 2000 , 0);
// Send message to the client socket pthread_mutex_lock(&lock); char *message = malloc(sizeof(client_message)+20); strcpy(message,"Hello Client : "); strcat(message,client_message); strcat(message,"\n"); strcpy(buffer,message); free(message); pthread_mutex_unlock(&lock); sleep(1); send(newSocket,buffer,13,0); printf("Exit socketThread \n"); close(newSocket); pthread_exit(NULL); }
int main(){ int serverSocket, newSocket; struct sockaddr_in serverAddr; struct sockaddr_storage serverStorage; socklen_t addr_size;
//Create the socket. serverSocket = socket(PF_INET, SOCK_STREAM, 0);
// Configure settings of the server address struct // Address family = Internet serverAddr.sin_family = AF_INET;
//Set port number, using htons function to use proper byte order serverAddr.sin_port = htons(7799);
//Set IP address to localhost serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
//Set all bits of the padding field to 0 memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
//Bind the address struct to the socket bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
//Listen on the socket, with 40 max connection requests queued if(listen(serverSocket,50)==0) printf("Listening\n"); else printf("Error\n"); pthread_t tid[60]; int i = 0; while(1) { //Accept call creates a new socket for the incoming connection addr_size = sizeof serverStorage; newSocket = accept(serverSocket, (struct sockaddr *) &serverStorage, &addr_size);
//for each client request creates a thread and assign the client request to it to process //so the main thread can entertain next request if( pthread_create(&tid[i++], NULL, socketThread, &newSocket) != 0 ) printf("Failed to create thread\n");
if( i >= 50) { i = 0; while(i < 50) { pthread_join(tid[i++],NULL); } i = 0; } } return 0; } |
멀티프로세스 방식
socket_server.c
#include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #include <arpa/inet.h> #include <fcntl.h> // for open #include <unistd.h> // for close #include <sys/types.h> #include <pthread.h> pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void socketThread(int clientSocket) {
char client_message[2000]; char buffer[1024];
int newSocket = clientSocket;
recv(newSocket , client_message , 2000 , 0);
// Send message to the client socket pthread_mutex_lock(&lock); char *message = malloc(sizeof(client_message)+20); strcpy(message,"Hello Client : "); strcat(message,client_message); strcat(message,"\n"); strcpy(buffer,message); free(message); pthread_mutex_unlock(&lock); sleep(1); send(newSocket,buffer,13,0); printf("Exit socketThread \n"); close(newSocket); }
int main(){ int serverSocket, newSocket; struct sockaddr_in serverAddr; struct sockaddr_storage serverStorage; socklen_t addr_size; pid_t pid[50]; //Create the socket. serverSocket = socket(PF_INET, SOCK_STREAM, 0);
// Configure settings of the server address struct // Address family = Internet serverAddr.sin_family = AF_INET;
//Set port number, using htons function to use proper byte order serverAddr.sin_port = htons(7799);
//Set IP address to localhost serverAddr.sin_addr.s_addr = inet_addr("0.0.0.0"); //Set all bits of the padding field to 0 memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
//Bind the address struct to the socket bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
//Listen on the socket, with 50 max connection requests queued if(listen(serverSocket,50)==0) printf("Listening\n"); else printf("Error\n"); int i = 0; while(1) { /* Accept call creates a new socket for the incoming connection */ addr_size = sizeof serverStorage; newSocket = accept(serverSocket, (struct sockaddr *) &serverStorage, &addr_size); int pid_c = 0;
if ((pid_c = fork())==0) { socketThread(newSocket); } else { pid[i++] = pid_c; if( i >= 49) { i = 0; while(i < 50) waitpid(pid[i++], NULL, 0); i = 0; } } } return 0; } |
클라이언트 소켓 파일
socket_client.c
#include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #include <arpa/inet.h> #include <stdlib.h> #include <fcntl.h> // for open #include <unistd.h> // for close #include<pthread.h>
void * cientThread(void *arg) { printf("In thread\n"); char message[1000]; char buffer[1024]; int clientSocket; struct sockaddr_in serverAddr; socklen_t addr_size;
// Create the socket. clientSocket = socket(PF_INET, SOCK_STREAM, 0);
//Configure settings of the server address // Address family is Internet serverAddr.sin_family = AF_INET;
//Set port number, using htons function serverAddr.sin_port = htons(7799);
//Set IP address to localhost serverAddr.sin_addr.s_addr = inet_addr("localhost"); memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
//Connect the socket to the server using the address addr_size = sizeof serverAddr; connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size); strcpy(message,"Hello");
if( send(clientSocket , message , strlen(message) , 0) < 0) { printf("Send failed\n"); }
//Read the message from the server into the buffer if(recv(clientSocket, buffer, 1024, 0) < 0) { printf("Receive failed\n"); } //Print the received message printf("Data received: %s\n",buffer); close(clientSocket); pthread_exit(NULL); } int main(){ int i = 0; pthread_t tid[51]; while(i< 50) { if( pthread_create(&tid[i], NULL, cientThread, NULL) != 0 ) printf("Failed to create thread\n"); i++; } sleep(20); i = 0; while(i< 50) { pthread_join(tid[i++],NULL); printf("%d:\n",i); } return 0; } |
[출처] https://dzone.com/articles/parallel-tcpip-socket-server-with-multi-threading
[수정] 출처의 예제에 오타가 있어서 바로 실행하면 에러가 발생합니다. 소스를 보완하여 작성하였습니다.
'프로그래밍 > C, C++' 카테고리의 다른 글
Visual Studio 2019 설치 (C / C++컴파일러) 및 몇가지 컴파일 에러 해결 방법 (0) | 2021.04.19 |
---|---|
Windows 에서 c 컴파일러 MinGW 설치하기 (0) | 2021.04.19 |
c언어 파일 이벤트 감시 (inotify) (0) | 2021.02.24 |
c언어 마지막줄 문자열 중복 출력하지 않기 (0) | 2021.02.24 |
c언어 string 문자형을 int 형으로 변환하기 (0) | 2021.02.24 |