동시 통신
서버는 다중 프로세스를 사용하여 세 개의 프로세스를 만들었습니다. 부모 프로세스는 클라이언트의 연결 상황을 검사하는 데 사용되고, 하위 프로세스는 클라이언트의 메시지를 수신하는 데 사용되며, 손 프로세스는 연결된 클라이언트에게 "hello"를 보내는 데 사용됩니다.
코드 구조를 최적화하기 위해 서버의 수신 메시지와 발송 메시지는 모두 execl 함수를 사용하여 봉인됩니다.
클라이언트는 다중 스레드를 사용합니다. 메인 스레드는 서버에 메시지를 보내는 데 사용되고, 2차 스레드는 서버의 안부를 받는 데 사용됩니다.
문제가 발생했습니다: 클라이언트가 강제로 종료할 때 서버 측에서 SIGPIPE를 보내는 이상이 발생합니다.
해결 방법: 전송 함수에서 시그널 신호 함수를 사용하여 SIGPIPE 신호를 무시하고 프로세스를 종료합니다.
비고: 간단하게 학습하고 통신을 할 뿐 코드를 세밀하게 최적화하지 않고 버그가 존재한다.
서버 코드:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PORT 8888
int main()
{
int sockfd;
int cfd;
int ret;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int clen;
char buf[1024];
pid_t pid;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
perror("socket");
exit(1);
}
printf("socket success!
");
int opt = 1;
setsockopt(sockfd, SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = inet_addr("192.168.1.16");
ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)); //(struct sockaddr *)&
if (ret == -1)
{
perror("bind");
exit(1);
}
printf("bind success!
");
ret = listen(sockfd, 5);
if (ret == -1)
{
perror("listen");
exit(1);
}
printf("listen success!
");
clen = sizeof(client_addr);
while (1)
{
bzero(&client_addr, sizeof(client_addr));
cfd = accept(sockfd, (struct sockaddr *)&client_addr, &clen);
if (cfd == -1)
{
perror("accept");
exit(1);
}
printf("accept success!
");
printf("client port = %d,client ip = %s
",ntohs(client_addr.sin_port), inet_ntoa(client_addr.sin_addr));
// , , ,
pid = fork();
if (pid < 0)
{
perror("fork");
exit(1);
}
else if (pid > 0)
{
close(cfd); // cfd,
}
else
{
char cfd_buf[1024]; // cfd
memset(cfd_buf, 0, sizeof(cfd_buf));
sprintf(cfd_buf, "%d", cfd); // cfd cfd_buf
// atoi()
pid_t pid2 = fork();
if (pid2 < 0)
{
perror("fork2");
exit(1);
}
else if (pid2 > 0)
{
execl("./recv_msg", "./recv_msg", cfd_buf, NULL);
}
else
{
execl("./send_msg", "./send_msg", cfd_buf, NULL);
}
}
}
close(sockfd);
return 0;
}
서버 메시지 보내기send_msg():
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
int ret;
int cfd = atoi(argv[1]); // ,
while (1)
{
ret = send(cfd, "hello", strlen("hello"), 0);
signal(SIGPIPE, SIG_IGN);
if (ret < 0)
{
perror("send");
_exit(1);
}
else if (ret == 0)
{
printf("%d is exit!
", cfd);
_exit(1);
}
else
{
sleep(2);
}
}
}
서버 수신 메시지 recv_msg():
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char*argv[])
{
int ret;
char buf[1024];
int cfd = atoi(argv[1]);
while (1)
{
memset(buf, 0, sizeof(buf));
ret = recv(cfd, buf, sizeof(buf), 0); //0
if (ret < 0)
{
perror("recv");
exit(1);
}
else if (ret == 0)
{
printf("%d is exit!(child)
", cfd);
shutdown(cfd, SHUT_RDWR);
_exit(1);
}
else
{
printf("recv : %s
", buf);
}
}
return 0;
}
클라이언트 코드:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PORT 8888
void *recv_msg(void *arg)
{
int ret;
char buf[1024];
int cfd = *((int *)arg);
while (1)
{
memset(buf, 0, sizeof(buf));
ret = recv(cfd, buf, sizeof(buf), 0);
if (ret < 0)
{
perror("recv");
exit(1);
}
else if (ret == 0)
{
printf("%d is exit
", cfd);
pthread_exit(NULL);
}
else
{
printf("client recv: %s
", buf);
}
}
pthread_exit(NULL);
}
int main()
{
int sockfd;
int ret;
char buf[1024];
pthread_t thread;
struct sockaddr_in server_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
perror("socket");
exit(1);
}
printf("socket success!
");
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = inet_addr("192.168.1.16");
ret = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (ret == -1)
{
perror("connect");
exit(1);
}
printf("connect success!
");
if (pthread_create(&thread, NULL, recv_msg, (void *)&sockfd) != 0)
{
perror("pthread create");
exit(1);
}
while (1)
{
memset(buf, 0, sizeof(buf));
printf("please input send message:
");
gets(buf);
send(sockfd, buf, strlen(buf), 0);
}
shutdown(sockfd, SHUT_RDWR);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.