관리 메뉴

Gyejoong's Information

TCP IP 소켓프로그래밍 소스코드(daytime,qotd,echo,finger) 본문

Study/Socket programming

TCP IP 소켓프로그래밍 소스코드(daytime,qotd,echo,finger)

연계중 2016. 9. 28. 20:11
반응형

Daytime 클라이언트 소스코드

 

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
void err_quit(const char *message);
void err_sys (const char *message);
#define MAXLINE 4096 /* max text line length */

int main(int argc, char *argv[])
{
 if (argc != 2)
  err_quit("usage: daytimetcpcli <IPaddress>");

 // 연결지향형 tcp 소켓 생성 (socket)
 int sockfd;
 if ( (sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
  err_sys("socket error");

 // 서버에 접속 (connect)
 struct sockaddr_in servaddr;
 memset(&servaddr,0,sizeof(servaddr));
 servaddr.sin_family = AF_INET;
 servaddr.sin_port   = htons(13); /* daytime port */
 int ret;
 if ( (ret = inet_pton(AF_INET,argv[1],&servaddr.sin_addr)) < 0)
  err_sys("inet_pton error");
 else if (!ret)
  err_quit("<IPaddress> error: not a valid network address string");

 if (connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
  err_sys("connect error");

 // 날짜/시간 문자열 수신 (read) 및 출력
 int n;
 char recvline[MAXLINE+1];
 while ( (n = read(sockfd,recvline,MAXLINE)) > 0){
  recvline[n] = 0; /* null terminate */
  if (fputs(recvline,stdout) == EOF)
   err_sys("fputs error");
 }
 if (n < 0)
  err_sys("read error");

 // 접속 종료/프로그램 종료 (close, exit)
 close(sockfd);
 exit(0);
}

void err_quit(const char *message)
{
 fputs(message,stderr);
 fputc('\n',stderr);
 exit(1);
}

void err_sys (const char *message)
{
 perror(message);
 exit(1);
}

 

Daytime 서버 소스코드

 


#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <time.h>
void err_quit(const char *message);
void err_sys (const char *message);
#define MAXLINE 4096 /* max text line length */

int main(int argc, char *argv[])
{
 // 연결지향형 tcp 소켓 생성 (socket)
 int listenfd;
 if ( (listenfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
  err_sys("socket error");

 // 서버주소와 소켓을 연결 (bind)
 struct sockaddr_in servaddr;
 memset(&servaddr,0,sizeof(servaddr));
 servaddr.sin_family = AF_INET;
 servaddr.sin_port   = htons(13); /* daytime port */
 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
 if (bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
  err_sys("bind error");

 // 소켓을 리슨소켓으로 변경 (listen)
 if (listen(listenfd,SOMAXCONN) < 0)
  err_sys("listen error");

 for ( ; ; ) {
  // 클라이언트 접속대기및처리 (accept)
  int connfd;
  struct sockaddr_in cliaddr;
  socklen_t len = sizeof(cliaddr);
  if ( (connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&len)) < 0)
   err_sys("accept error");

  // 접속한 클라이언트의 정보를 화면에 출력
  char cliname[INET_ADDRSTRLEN];
  if ( inet_ntop(AF_INET,&cliaddr.sin_addr,cliname,sizeof(cliname)) )
   printf("Handling client %s:%d\n",cliname,ntohs(cliaddr.sin_port));
  else
   err_sys("inet_ntop error");

  // daytime 문자열을 송신 (write)
  time_t ticks = time(NULL);
  char buff[MAXLINE];
  snprintf(buff,sizeof(buff),"%.24s\r\n",ctime(&ticks));
  if (write(connfd,buff,strlen(buff)) < 0)
   err_sys("write error");

  // 클라이언트의 접속 종료 (close)
  close(connfd);
 } // 무한 반복 (for, while)
}

void err_quit(const char *message)
{
 fputs(message,stderr);
 fputc('\n',stderr);
 exit(1);
}

void err_sys (const char *message)
{
 perror(message);
 exit(1);
}

 

 

quote of the day 클라이언트 소스코드

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
void err_quit(const char *message);
void err_sys (const char *message);
#define MAXLINE 4096 /* max text line length */

int main(int argc, char *argv[])
{
 if (argc != 2)
  err_quit("usage: qotdtcpcli <IPaddress>");

 // 연결지향형 tcp 소켓 생성 (socket)
 int sockfd;
 if ( (sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
  err_sys("socket error");

 // 서버에 접속 (connect)
 struct sockaddr_in servaddr;
 memset(&servaddr,0,sizeof(servaddr));
 servaddr.sin_family = AF_INET;
 servaddr.sin_port   = htons(17); /* quote of the day port */
 int ret;
 if ( (ret = inet_pton(AF_INET,argv[1],&servaddr.sin_addr)) < 0)
  err_sys("inet_pton error");
 else if (!ret)
  err_quit("<IPaddress> error: not a valid network address string");

 if (connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
  err_sys("connect error");


 // 오늘의 명언 문자열 수신 (read) 및 출력
 int n;
 char recvline[MAXLINE+1];
 while ( (n = read(sockfd,recvline,MAXLINE)) > 0){
  recvline[n] = 0; /* null terminate */
  if (fputs(recvline,stdout) == EOF)
   err_sys("fputs error");
 }
 if (n < 0)
  err_sys("read error");

 // 화면에 모두 출력되게 하도록 newLine 출력
 printf("\n");

 // 접속 종료/프로그램 종료 (close, exit)
 close(sockfd);
 exit(0);
}

void err_quit(const char *message)
{
 fputs(message,stderr);
 fputc('\n',stderr);
 exit(1);
}

void err_sys (const char *message)
{
 perror(message);
 exit(1);
}

 

 

echo 클라이언트 소스코드

 

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include "common.h"
void    err_quit(const char *message);
void    err_sys (const char *message);
void    str_cli (FILE *fp, int sockfd);
#define MAXLINE 4096 /* max text line length */

int main(int argc, char *argv[])
{
 if (argc != 2)
  err_quit("usage: echotcpcli <IPaddress>");

 // 연결지향형 tcp 소켓 생성 (socket)
 int sockfd;
 if ( (sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
  err_sys("socket error");

 // 서버에 접속 (connect)
 struct sockaddr_in servaddr;
 memset(&servaddr,0,sizeof(servaddr));
 servaddr.sin_family = AF_INET;
 servaddr.sin_port   = htons(7); /* echo port */
 int ret;
 if ( (ret = inet_pton(AF_INET,argv[1],&servaddr.sin_addr)) < 0)
  err_sys("inet_pton error");
 else if (!ret)
  err_quit("<IPaddress> error: not a valid network address string");

 if (connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
  err_sys("connect error");

 // 에코 문자열 송신(write) 및 수신(read)
 str_cli(stdin,sockfd);

 // 접속 종료/프로그램 종료 (close, exit)
 close(sockfd);
 exit(0);
}

void str_cli (FILE *fp, int sockfd)
{
 char sendline[MAXLINE], recvline[MAXLINE];

 while (fgets(sendline,MAXLINE,fp) != NULL){
  if (writen(sockfd,sendline,strlen(sendline)) < 0)
   err_sys("writen error");

  int n;
  if ( (n = readline(sockfd,recvline,MAXLINE)) < 0)
   err_sys("readline error");
  else if (n == 0)
   err_quit("str_cli: server terminated prematurely");

  recvline[n] = 0; /* null terminate */
  if (fputs(recvline,stdout) == EOF)
   err_sys("fputs error");
 }
}

void err_quit(const char *message)
{
 fputs(message,stderr);
 fputc('\n',stderr);
 exit(1);
}

void err_sys (const char *message)
{
 perror(message);
 exit(1);
}

 

 

 

common.h 소스코드

 

#ifndef _COMMON_H_
#define _COMMON_H_

 

ssize_t writen  (int filedes, const void *buff, size_t nbytes);
ssize_t readline(int filedes, void *buff, size_t maxlen);

 

#endif /*_COMMON_H_*/

 

 

readline.c 소스코드

 

 

#include <stdio.h>
#include <errno.h>
#include <unistd.h>

/* PAINFULLY LESS SLOW VERSION -- example only */
ssize_t readline(int fd, void *vptr, size_t maxlen)
{
 ssize_t n, rc;
 char    c, *ptr;
 ptr = vptr;
 for (n = 1; n < maxlen; n++) {
  again:
   if ( (rc = read(fd, &c, 1)) == 1) {
    *ptr++ = c;
    if (c == '\n')
     break;      /* newline is stored, like fgets() */
   } else if (rc == 0) {
    *ptr = 0;
    return (n - 1);   /* EOF, n - 1 bytes were read */
   } else {
    if (errno == EINTR)
     goto again;
    return (-1);    /* error, errno set by read() */
   }
 }
 *ptr = 0;         /* null terminate like fgets() */
 return (n);
}

 

writen.c 소스코드

 

 

#include <stdio.h>
#include <errno.h>
#include <unistd.h>

/* Write "n" bytes to a descriptor. */
ssize_t writen(int fd, const void *vptr, size_t n)
{
 size_t nleft;
 ssize_t nwritten;
 const char *ptr;

 ptr = vptr;
 nleft = n;
 while (nleft > 0) {
  if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
   if (nwritten < 0 && errno == EINTR)
    nwritten = 0; /* and call write() again */
   else
    return (-1); /* error */
  }
  
  nleft -= nwritten;
  ptr += nwritten;
 }
 return (n);

 

 

Echo 서버 소스코드

 

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include "common.h"
void err_quit(const char *message);
void err_sys (const char *message);
void str_echo(int sockfd);
#define MAXLINE 4096 /* max text line length */

int main(int argc, char *argv[])
{
 // 연결지향형 tcp 소켓 생성 (socket)
 int listenfd;
 if ( (listenfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
  err_sys("socket error");

 // 서버주소와 소켓을 연결 (bind)
 struct sockaddr_in servaddr;
 memset(&servaddr,0,sizeof(servaddr));
 servaddr.sin_family = AF_INET;
 servaddr.sin_port   = htons(7); /* echo port */
 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
 if (bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
  err_sys("bind error");

 // 소켓을 리슨소켓으로 변경 (listen)
 if (listen(listenfd,SOMAXCONN) < 0)
  err_sys("listen error");

 for ( ; ; ) {
  // 클라이언트 접속대기및처리 (accept)
  int connfd;
  struct sockaddr_in cliaddr;
  socklen_t len = sizeof(cliaddr);
  if ( (connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&len)) < 0)
   err_sys("accept error");

  // 접속한 클라이언트의 정보를 화면에 출력
  char cliname[INET_ADDRSTRLEN];
  if ( inet_ntop(AF_INET,&cliaddr.sin_addr,cliname,sizeof(cliname)) )
   printf("Handling client %s:%d\n",cliname,ntohs(cliaddr.sin_port));
  else
   err_sys("inet_ntop error");

  pid_t childpid;
  if ( (childpid = fork()) < 0) // fork error
   err_sys("fork error");
  else if (childpid == 0){   // child process
   close(listenfd); /* close listening socket */
   str_echo(connfd); /* process the request */
   exit(0);
  }

  // parent process
  close(connfd);   /* parent closes connected socket */

 } // 무한 반복 (for, while)
}

void str_echo(int sockfd)
{
 ssize_t n;
 char    line[MAXLINE];

 for ( ; ; ) {
  if ( (n = readline(sockfd,line,MAXLINE)) < 0)
   err_sys("read error");
  else if (n == 0)
   return;  /* connection closed by other end */

  if (writen(sockfd,line,n) < 0)
   err_sys("write error");
 }
}

void err_quit(const char *message)
{
 fputs(message,stderr);
 fputc('\n',stderr);
 exit(1);
}

void err_sys (const char *message)
{
 perror(message);
 exit(1);
}

 

 

finger 클라이언트 소스코드

 

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include "common.h"
void    err_quit(const char *message);
void    err_sys (const char *message);
void    str_cli (FILE *fp, int sockfd);
#define MAXLINE 4096 /* max text line length */

int main(int argc, char *argv[])
{
 if (argc != 2)
  err_quit("usage: fingertcpcli <IPaddress>");

 // 연결지향형 tcp 소켓 생성 (socket)
 int sockfd;
 if ( (sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
  err_sys("socket error");

 // 서버에 접속 (connect)
 struct sockaddr_in servaddr;
 memset(&servaddr,0,sizeof(servaddr));
 servaddr.sin_family = AF_INET;
 servaddr.sin_port   = htons(79); /* finger port */
 int ret;
 if ( (ret = inet_pton(AF_INET,argv[1],&servaddr.sin_addr)) < 0)
  err_sys("inet_pton error");
 else if (!ret)
  err_quit("<IPaddress> error: not a valid network address string");

 if (connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
  err_sys("connect error");

 // finger 문자열 송신(write) 및 수신(read)
 str_cli(stdin,sockfd);

 // 접속 종료/프로그램 종료 (close, exit)
 close(sockfd);
 exit(0);
}

void str_cli (FILE *fp, int sockfd)
{
 char sendline[MAXLINE], recvline[MAXLINE];

 if (fgets(sendline,MAXLINE,fp) == NULL)
  err_sys("fgets error");

 if (writen(sockfd,sendline,strlen(sendline)) < 0)
  err_sys("writen error");

 int n;
 while ( (n = read(sockfd,recvline,MAXLINE)) > 0){
  recvline[n] = 0; /* null terminate */
  if (fputs(recvline,stdout) == EOF)
   err_sys("fputs error");
 }
 if (n < 0)
  err_sys("read error");
}

void err_quit(const char *message)
{
 fputs(message,stderr);
 fputc('\n',stderr);
 exit(1);
}

void err_sys (const char *message)
{
 perror(message);
 exit(1);
}

 

 

반응형

'Study > Socket programming' 카테고리의 다른 글

클라이언트 공용코드(daytime,qotd,echo,finger)  (0) 2016.09.30
Socket Programming 정리  (0) 2016.09.28
daytime서버 코딩  (0) 2016.09.12
Comments