socket 네트워크 프로 그래 밍 의 2 (리 턴 프로그램 인 스 턴 스)
주의!github 의 소스 코드 는 제 가 UNIX 네트워크 프로 그래 밍 을 공부 하 는 과정 에서 책의 소스 코드 를 실현 하 는 것 입 니 다. 일련의 소스 코드 입 니 다. 보완 중 입 니 다. echo Program 폴 더 의 코드 와 이 블 로그 가 대응 합 니 다. 다운로드 한 후에 'README 파일' 을 먼저 보 세 요.코드 중의 일부 공공 함수, 예 를 들 어 오류 처리 와 소포 함 수 는 모두 Public 폴 더 아래 에 놓 여 있 습 니 다.패키지 함 수 는 일부 기본 함수 가 오류 처리 조작 을 포함 하고 있 으 므 로 여러분 은 한눈 에 알 수 있 습 니 다.
조심해!!!모든 소스 코드, 저 는 xcodeIDE 를 사용 하여 이 루어 졌 습 니 다. IOS 프로그램 원숭이 하 나 를 사용 할 수 없습니다. 여러분 은 다른 개발 환경 에서 뛰 어야 합 니 다. 스스로 이식 하 십시오!모든 소스 코드, 저 는 xcodeIDE 를 사용 하여 이 루어 졌 습 니 다. IOS 프로그램 원숭이 하 나 를 사용 할 수 없습니다. 여러분 은 다른 개발 환경 에서 뛰 어야 합 니 다. 스스로 이식 하 십시오!모든 소스 코드, 저 는 xcodeIDE 를 사용 하여 이 루어 졌 습 니 다. IOS 프로그램 원숭이 하 나 를 사용 할 수 없습니다. 여러분 은 다른 개발 환경 에서 뛰 어야 합 니 다. 스스로 이식 하 십시오!
클 라 이언 트 코드
int sockfd;
struct sockaddr_in sockaddr;
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&sockaddr, sizeof(sockaddr));
sockaddr.sin_port = htons(9999);
sockaddr.sin_family = AF_INET;
inet_pton(AF_INET,"127.0.0.1",&sockaddr.sin_addr);
Connect(sockfd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
str_cli(stdin, socked);
void str_cli(FILE *fd,int sockfd){
char sendline[MAXLINE],recvline[MAXLINE];
ssize_t status;
while ( Fgets(sendline, MAXLINE, fd)!=NULL ) {
Writen(sockfd, sendline, strlen(sendline));
status = read(sockfd, recvline, MAXLINE);
if ( status< 0 ) {
err_sys("read error");
}
puts(recvline);
}
}
이로부터 strcli 함수 가 완성 되 었 습 니 다. 정상 적 인 상황 에서 이 프로그램 은 아무런 문제 가 없 지만 예외 적 인 상황 이 있 습 니 다. 프로그램 이 fgets 함수 에 막 히 는 동안 서버 프로그램 이 무 너 지면 서버 프로그램 은 연결 을 닫 아 달 라 는 요청 을 보 냅 니 다. 이때 클 라 이언 트 프로그램 은 모 릅 니 다.그 다음 에 사용자 가 텍스트 를 입력 하면 fgets 가 차단 을 해제 하고 write 함 수 를 호출 합 니 다. 서버 가 연결 을 닫 았 기 때문에 write 함 수 는 기록 에 성공 하지 못 할 것 입 니 다. 이렇게 찍 은 문 제 는 클 라 이언 트 가 fgets 에 차단 되 어 서버 의 상황 을 제때에 알 지 못 하기 때문에 이렇게 쓴 프로그램 에 문제 가 있 습 니 다. 따라서 우 리 는 selece 함수 로 이 문 제 를 해결 하 는 것 을 고려 합 니 다.다음은 strcli 의 select 버 전.
void str_cli(FILE *fd,int sockfd){
int maxfdp1;
fd_set rset;
char sendline[MAXLINE],recvline[MAXLINE];
ssize_t readlen;
// fd_set 0
FD_ZERO(&rset);
for (; ; ) {
//FD_SET
FD_SET(fileno(fd),&rset);
FD_SET(sockfd,&rset);
// maxfdp1 +1 0
maxfdp1 = ((int)fmaxf(fileno(fd), sockfd)) + 1;
Select(maxfdp1, &rset, NULL, NULL, NULL);
//FD_ISSET , sockfd
if ( FD_ISSET(sockfd,&rset) ) {
readlen = read(sockfd, recvline, MAXLINE);
// 0
if ( readlen==0 ) {
err_quit("server terminal");
}
if ( readlen < 0 ) {
err_sys("read error");
}
//
puts(recvline);
}
if ( FD_ISSET(fileno(fd),&rset) ) {
if ( Fgets(sendline, MAXLINE, fd)==NULL ) {
return;
}
Writen(sockfd, sendline, MAXLINE);
}
}
}
우 리 는 select 함수 로 해결 할 수 있 습 니 다. fgets 함수 가 차단 상태 에서 서버 가 연결 을 닫 았 을 때 클 라 이언 트 프로그램 이 즉시 알 수 없 는 상황 입 니 다.
서버 코드
int listenfd,connfd;
pid_t childPid;
socklen_t clilen;
struct sockaddr_in cliaddr,seraddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&seraddr, sizeof(seraddr));
seraddr.sin_port = htons(9999);
seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
seraddr.sin_family = AF_INET;
Bind(listenfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
Listen(listenfd,LISTENQ);
Sigal(SIGCHLD, sig_child);
for ( ; ; ) {
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
// 0
if ( ( childPid = Fork() ) == 0 ) {
printf(" :%d",getpid());
Close( listenfd );
str_echo(connfd);
exit(0);
}
Close(connfd); /* */
}
void str_echo(int sockfd)
{
ssize_t n;
char buf[MAXLINE];
again:
while ( (n = read(sockfd, buf, MAXLINE)) > 0 ) {
Writen(sockfd, buf, n);
}
if ( n < 0 && errno == EINTR )
goto again;
else if (n < 0)
err_sys("str_echo: read error");
}
void sig_child(int signo)
{
pid_t pid;
int stat;
printf(" :%d",getpid());
printf("signal num = %d",signo);
//pid = wait(&stat);
//waitpid
//printf("child %d terminated
",pid);
while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0 ) {
printf("child %d terminated
",pid);
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.