질문&답변
클라우드/리눅스에 관한 질문과 답변을 주고 받는 곳입니다.
리눅스 분류

제발 이것좀... ㅠㅠ

작성자 정보

  • 간절한남 작성
  • 작성일

컨텐츠 정보

본문

이번학기에 소켓프로그램 처음으로 접한 학생인데요
소켓프로그램 재밌긴 한데 어렵네요.. ㅠㅠ
이번학기까지 I/O멀티플렉싱 기법까지 배웠는데요
학기말 과제로 스래드 기반의 HTTP 서버를 I/O멀티 플랙싱 기반의 서버로 수정하는
겁니다.. 나름데로 열씨미 해 보았지만.. 기간이 다 되서 낼 제출해야하네여.. ㅠㅠ
정말 열씨미 해봤는데 모르겠어여..ㅠㅠ 부탁드립니다..
밑의 소스 스래드 형식을 I/O멀티플랙싱 형식으로좀 바꿔주세요..
스래스 소스 밑에 제가 나름데로 작성해본 I/O멀티플랙싱 형식입니다..
틀린거라서... 리눅스 최강유저님들... 부탁해요.. ㅠㅠ

<스래드 소스>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>

#define LINESIZE 1024
#define MAXPENDING 20


void * serviceThread(void *args);
void doHTTPService(int clntSock);
int readLine(int clntsock, char *line);
void sendFile(int clntsock, char *fileName);
void sendError400(int clntsock);
void sendError404(int clntSock);
void DieWithError(char *errorMessage);

struct ThreadArgs{
 int clntSock;
};

int main(int argc, char **argv)
{
 int servSock;
 int clntSock;

 struct sockaddr_in servAddr;
 struct sockaddr_in clntAddr;

 int clntAddrLen;
 pthread_t thread;
 struct ThreadArgs *threadArgs;
 
 if(argc != 2){
  printf("Usage : %s <port> ", argv[0]);
  exit(0);
 }
 
 servSock=socket(PF_INET, SOCK_STREAM, 0);
 if(servSock == -1)
  DieWithError("socket error");

 memset(&servAddr, 0, sizeof(servAddr));
 
 servAddr.sin_family = AF_INET;
 servAddr.sin_addr.s_addr=htonl(INADDR_ANY);
 servAddr.sin_port=htons(atoi(argv[1]));
 
 if(bind(servSock, (struct sockaddr *) &servAddr, sizeof(servAddr)) == -1)
  DieWithError("bind() error");
 if(listen(servSock, MAXPENDING) == -1)
  DieWithError("listen() error");
 

 while(1) {
  clntAddrLen=sizeof(clntAddr);
  clntSock=accept(servSock, (struct sockaddr *) &clntAddr, &clntAddrLen);
  printf("connection request : %s:%d ", inet_ntoa(clntAddr.sin_addr), ntohs(clntAddr.sin_port));
  if((threadArgs=(struct ThreadArgs *)malloc(sizeof(struct ThreadArgs)))==NULL)
   DieWithError("malloc() error");
     
  threadArgs->clntSock=clntSock;
  pthread_create(&thread, NULL, serviceThread, (void *) threadArgs);
  }
 return 0;
}


void *serviceThread(void *args)
{
 int cSock;

 pthread_detach(pthread_self());
 cSock=((struct ThreadArgs *) args)->clntSock;
 free(args);

 doHTTPService(cSock);
 close(cSock);
}

void doHTTPService(int clntSock)
{
 int lineLen;
 char reqLine[LINESIZE];
 char method[10];
 char fileName[30];

 while(lineLen=readLine(clntSock, reqLine)){
  fprintf(stderr, "       %s ", reqLine);
  if(strstr(reqLine, "HTTP/")){
   strcpy(method, strtok(reqLine, " /"));
   strcpy(fileName, strtok(NULL, " /"));
  }
 }
 if(strcmp(method, "GET") !=0) {
  sendError400(clntSock);
 }
 sendFile(clntSock, fileName);
}

int readLine(int sock, char *line)
{
 char buf[LINESIZE];
 int len, pos;
 char ch;
 pos=0;
 while(1){
  ch='';
  len=recv(sock, &ch, 1, 0);
  if(len < 0)
   DieWithError("recv() error in readLine() ");
  if(len==0){
   strcpy(line, buf);
   return pos;
  }
  buf[pos++]=ch;
  if((pos>=1) && (buf[pos-1]==' ')) {
   if((pos >= 2) && (buf[pos-2]==' ')){
   buf[pos-2]='0';
   pos -= 2;
   break;
  }
  else{
   buf[pos-1]='';
   pos -= 1;
   break;
  }
 }
}
 strcpy(line, buf);
 return(pos);
}

void sendFile(int clntSock, char* fileName)
{
 FILE * fp;
 char protocol[]="HTTP/1.1 200 OK ";
 char server[]="Server:My HTTP Server ";
 char clength[]="Content-length:1024 ";
 char ctype[]="Content-type:text/html ";
 char buf[LINESIZE];

 if((fp=fopen(fileName, "r"))==NULL){
  sendError404(clntSock);
  return;
 }
 
 send(clntSock, protocol, sizeof(protocol), 0);
 send(clntSock, server, sizeof(server), 0);
 send(clntSock, clength, sizeof(clength), 0);
 send(clntSock, ctype, sizeof(ctype), 0);

 while(fgets(buf, LINESIZE, fp) != NULL)
 {
  strtok(buf, " ");
  send(clntSock, buf, strlen(buf), 0);
 }
 fclose(fp);
}

void sendError400(int clntSock)
{
 char protocol[]="http/1.1 400 Bad Request ";
 char server[]="server: My Http Server ";
 char clength[]="Content=length:1024 ";
 char ctype[]="Content-type: text/html ";
 
 char message[]="<body><font size =+5>400: Bad Request Method!</font></body>";

 send(clntSock, protocol, sizeof(protocol), 0);
 send(clntSock, server, sizeof(server), 0);
 send(clntSock, clength, sizeof(clength), 0);
 send(clntSock, ctype, sizeof(ctype), 0);
 send(clntSock, message, sizeof(message), 0);
}

void sendError404(int clntSock)
{
 char protocol[]="http/1.1 200 Bad Request ";
 char server[]="server: My Http server ";
 char clength[]="Content-length:1024 ";
 char ctype[]="Content-type: text/html ";

 char message[]="<body><font size=+5>404 File Not Found!</font></body>";

 send(clntSock, protocol, sizeof(protocol), 0);
 send(clntSock, server, sizeof(server), 0);
 send(clntSock, clength, sizeof(clength), 0);
 send(clntSock, ctype, sizeof(ctype), 0);
 send(clntSock, message, sizeof(message), 0);
}

void DieWithError(char *errorMessage)
{
 perror(errorMessage);
 exit(1);
}

<이것을 제 나름데로 멀티플랙싱 형식으로 바꾼것.. >

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define LINESIZE 1024
#define MAXPENDING 20
#define BUFSIZE 100

void doHTTPService(int clntSock);
int readLine(int clntSock, char *line);
void sendFile(int clntSock, char *fileName);
void sendError400(int clntSock);
void sendError404(int clntSock);
void DieWithError(char *errorMessage);

int main(int argc, char **argv)

 int servSock;
 int clntSock;
 struct sockaddr_in clntAddr, servAddr;
 int fd, strlen;
 int clntlen;
 char message[BUFSIZE];
 fd_set reads, temps;

 if(argc != 2){
  printf("Usage : %s <port> ", argv[0]);
  exit(1);
}

 servSock=socket(PF_INET, SOCK_STREAM, 0);
 if(servSock == -1)
  DieWithError("socket error");

 memset(&servAddr, 0, sizeof(servAddr));
 
 servAddr.sin_family = AF_INET;
 servAddr.sin_addr.s_addr=htonl(INADDR_ANY);
 servAddr.sin_port=htons(atoi(argv[1]));
 
 if(bind(servSock, (struct sockaddr *) &servAddr, sizeof(servAddr)) == -1)
  DieWithError("bind() error");
 if(listen(servSock, MAXPENDING) == -1)
  DieWithError("listen() error");
  
 FD_ZERO(&reads);
 FD_SET(servSock, &reads);

 while(1)
 {
  temps=reads;
  if(select(FD_SETSIZE, &temps, 0, 0, 0)<1){
   DieWithError("select() error");
   exit(1);
  }

 for(fd=0; fd<FD_SETSIZE; fd++)
 {
  if(FD_ISSET(fd, &temps))
        {
   if(fd==servSock) { /* 연결 요청인 경우 */
     clntlen = sizeof(clntAddr);
   clntSock = accept(servSock, (struct sockaddr*)&clntAddr, &clntlen);
     FD_SET(clntSock, &reads);
    printf("클라이언트 연결 : 파일 디스크립터 %d ", clntSock);
          }
  else {
    strlen = read(fd, message, BUFSIZE);
  if(strlen ==0){ /* 연결 종료 요청인 경우 */
      close(fd);
      FD_CLR(fd, &reads);
      printf("클라이언트 종료 : 파일 디스크립터 %d ", fd);
    }
    else{
      write(fd, message, strlen);
      doHTTPService(clntSock);
       } 
  }
      } //if(FD_ISSET(fd, &temps))
    } //for(fd=0; fd<fd_max+1; fd++)
  } //while(1) 
  return 0;
 }
 
void doHTTPService(int clntSock)
{
 int lineLen;
 char reqLine[LINESIZE];
 char method[10];
 char fileName[30];

 while(lineLen=readLine(clntSock, reqLine)){
  fprintf(stderr, "       %s ", reqLine);
  if(strstr(reqLine, "HTTP/")){
   strcpy(method, strtok(reqLine, " /"));
   strcpy(fileName, strtok(NULL, " /"));
  }
 }
 if(strcmp(method, "GET") !=0) {
  sendError400(clntSock);
 }
 sendFile(clntSock, fileName);
}

int readLine(int clntSock, char *line)
{
 char buf[LINESIZE];
 int len, pos;
 char ch;
 pos=0;
 while(1){
  ch='';
  len=recv(clntSock, &ch, 1, 0);
  if(len < 0)
   DieWithError("recv() error in readLine() ");
  if(len==0){
   strcpy(line, buf);
   return pos;
  }
  buf[pos++]=ch;
  if((pos>=1) && (buf[pos-1]==' ')) {
   if((pos >= 2) && (buf[pos-2]==' ')){
   buf[pos-2]='0';
   pos -= 2;
   break;
  }
  else{
   buf[pos-1]='';
   pos -= 1;
   break;
  }
 }
}
 strcpy(line, buf);
 return(pos);
}

void sendFile(int clntSock, char* fileName)
{
 FILE * fp;
 char protocol[]="HTTP/1.1 200 OK ";
 char server[]="Server:My HTTP Server ";
 char clength[]="Content-length:1024 ";
 char ctype[]="Content-type:text/html ";
 char buf[LINESIZE];

 if((fp=fopen(fileName, "r"))==NULL){
  sendError404(clntSock);
  return;
 }
 
 send(clntSock, protocol, sizeof(protocol), 0);
 send(clntSock, server, sizeof(server), 0);
 send(clntSock, clength, sizeof(clength), 0);
 send(clntSock, ctype, sizeof(ctype), 0);

 while(fgets(buf, LINESIZE, fp) != NULL)
 {
  strtok(buf, " ");
  send(clntSock, buf, strlen(buf), 0);
 }
 fclose(fp);
}

void sendError400(int clntSock)
{
 char protocol[]="http/1.1 400 Bad Request ";
 char server[]="server: My Http Server ";
 char clength[]="Content=length:1024 ";
 char ctype[]="Content-type: text/html ";
 
 char message[]="<body><font size =+5>400: Bad Request Method!</font></body>";

 send(clntSock, protocol, sizeof(protocol), 0);
 send(clntSock, server, sizeof(server), 0);
 send(clntSock, clength, sizeof(clength), 0);
 send(clntSock, ctype, sizeof(ctype), 0);
 send(clntSock, message, sizeof(message), 0);
}

void sendError404(int clntSock)
{
 char protocol[]="http/1.1 200 Bad Request ";
 char server[]="server: My Http server ";
 char clength[]="Content-length:1024 ";
 char ctype[]="Content-type: text/html ";

 char message[]="<body><font size=+5>404 File Not Found!</font></body>";

 send(clntSock, protocol, sizeof(protocol), 0);
 send(clntSock, server, sizeof(server), 0);
 send(clntSock, clength, sizeof(clength), 0);
 send(clntSock, ctype, sizeof(ctype), 0);
 send(clntSock, message, sizeof(message), 0);
}

void DieWithError(char *errorMessage)
{
 perror(errorMessage);
 exit(1);
}

낼까지 내야하는데 급한불 부터 꺼야하기에.. ㅠㅠ

관련자료

댓글 0
등록된 댓글이 없습니다.

공지사항


뉴스광장


  • 현재 회원수 :  60,076 명
  • 현재 강좌수 :  36,001 개
  • 현재 접속자 :  501 명