[완료]소켓 프로그래밍 중 명령어와 인자를 인식하는 부분이 잘 안되요ㅠ

theageha의 이미지

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
 
#define COMMAND_BUFSIZE 30
#define MESSAGE_BUFSIZE 500
 
int my_strcmp(const char *string1, const char *string2);
void error_handling(char *command);
 
int main(int argc, char **argv){
	int serv_sock;
	int clnt_sock;
 
	char rv_message[30];
 
	char command[COMMAND_BUFSIZE];
	char message[MESSAGE_BUFSIZE]="Hello World";
	int str_len;
	int clnt_addr_size;
 
	struct sockaddr_in serv_addr;
	struct sockaddr_in clnt_addr;
 
	struct hostent* hostp;
 
 
 
 
	clnt_addr_size=sizeof(clnt_addr);
 
	if(argc!=2){
		printf("Usage : %s <port>\n", argv[0]);
		exit(1);
	}
 
	if((serv_sock=socket(PF_INET, SOCK_STREAM, 0))<0)
		error_handling("serv socket() error");
 
 
 
	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family=AF_INET;
	serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	serv_addr.sin_port=htons(atoi(argv[1]));
 
 
	if(bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr))<0)
		error_handling("bind() error");
 
 
	if((listen(serv_sock, 5))<0)
		error_handling("listen() error");
 
 
	printf("Student ID : 20031943\n");
	printf("Name : Sungjin Park\n");
 
 
	for(;;){
		printf("WBS>");
		fgets(command, COMMAND_BUFSIZE, stdin);
 
		if(strcmp(command, "quit\n")==0 || strcmp(command, "QUIT\n")==0) 
			break;
 
		if(my_strcmp(command, "get")==0 || my_strcmp(command, "GET")==0){      ///이부분으로 안넘어가집니다.ㅠ
			if(argc!=3){
				printf("Usage : %s <IP> <port>\n", argv[0]);
				exit(1);
			}
			else
				exit(1);
 
 
			memset(&serv_addr, 0, sizeof(serv_addr));
			serv_addr.sin_addr.s_addr=inet_addr(argv[1]);
 
			if ((hostp = gethostbyaddr((char*)&serv_addr.sin_addr, 4, AF_INET))== 0) {
			fprintf(stderr,"%s: unknown host\n",argv[2]);
			exit(1);
			}
 
			serv_addr.sin_family=AF_INET;
			serv_addr.sin_port=htons(atoi(argv[2]));
 
			if((connect(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)))<0)
				error_handling("connect() error");
 
			if((str_len=read(serv_sock, rv_message, sizeof(rv_message)-1))<0)
				error_handling("read() error");
 
			rv_message[str_len]=0;
			printf("Message from server : %s \n", rv_message);
			close(serv_sock);
 
		}
		else{
			printf("Invalid command\n");
			continue;
		}
 
		if((clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size))<0)
		error_handling("accept() error");
 
		write(clnt_sock, message, clnt_addr_size);
 
		close(clnt_sock);
	}
 
	return 0;
}
 
void error_handling(char *command){
	fputs(command, stderr);
	fputc('\n', stderr);
	exit(1);
}
 
int my_strcmp(const char *string1, const char *string2){
 
	while(*string1==*string2 && !isspace(*string2)) {
			string1++;
			string2++;
	}
		if(*string1<*string2)
			return (-1);
		else if(*string1>*string2)
			return (1);
		else
			return (0);
	return 0;
}

----------------------
소스가 다소 복잡해보이지만, 프로그램의 목표는 이렇습니다.

1. 서버로 동작하여 어떠한 요청이 들어오면 처리할 수 있다.
동시에 또다른 서버로 요청을 할 수 있어야 한다.

2. 서버로의 요청은 Get 이라는 명령어에 의해서 판별된다.
즉, 서버로 유지되고 있다가 get 127.0.0.1 8080 a.xxx
라는 요청을 보내면 다른 서버에서 가진 a.xxx를 받아와야한다.

실은 학교 과제이긴 합니다. 혼자서 며칠 째 고민중인데....하다하다 정말 답답해서 올립니다.
명령어가 인식이 되어야 뒤에 소켓을 처리하고, http 요청 등등을 시도해볼텐데...
명령어조차 인식이 안되서...지금 좌절 직전이라서요ㅠ

ex) "quit\n" - 이렇게는 인식이 됩니다.
"quit" - 이렇게 해놓으면 인식이 안되구요.

왜그런지 모르겠습니다. 똑같이 strcmp 하는건데...혹시나 해서 my_strcmp까지 만들어서 비교하는데...ㅠ

제가 설명을 잘 했는지 모르겠지만...ㅠ 누가 좀 도와주세요...

승원의 이미지

fgets() 함수는 newline 문자까지 저장한다고 하니, "quit"이 아니라 "quit\n"과 문자열 비교를 하는게 맞는 것 같습니다.

그리고 명령어가 "get 127.0.0.1 8080 a.xxx"와 같이 주어진다면, strcmp() 함수 대신 strncmp() 함수를 써서 처음 세 개의 문자만 비교를 해야될 것 같습니다.
strncmp(command, "get", 3)처럼요.

제가 질문을 제대로 이해하고 답변을 드리는 건지 모르겠네요.

블로그 : http://jeongsw.tistory.com

theageha의 이미지

십년 묵은 체증이 내려가는 느낌이 이런거구나 싶을 정도로!!

알려주신대로 하니까 되네요..ㅠㅠ

그런데 get 127.0.0.1 8080 a.xxx 이런식으로 되어있을 때,

strncmp(command, "get", 1)을 해버리면

get은 비교해서 확인이 되는데, 뒤에 있는 인자들은..어떤식으로 변수나 함수에 넘겨줘야 할지...;;

ex) WBS> get hostname/IP address port filename

이때 host, port, filename을 인자로 어딘가로 넘기려고 하는데...

이게 프로그램 구동 중이라서 그런지 argv[1],[2] 등이 안 먹히는 거 같아서요..ㅠㅠ

저도 지금부터 고민해보겠지만, 혹시라도 아시면 답변 부탁드립니다.ㅠ
----------------------------------------------------------------------------
삼인행 필유아사언(三人行 必有我師焉) - 세 사람이 길을 가면 그 중에 반드시 스승이 있다.

----------------------------------------------------------------------------
삼인행 필유아사언(三人行 必有我師焉) - 세 사람이 길을 가면 그 중에 반드시 스승이 있다.

dong1036의 이미지

일단 위엣분이 말씀한 것 같이 fgets는 끝에 \n\0이 붙지요..\n을 붙지 않게 하고 싶다면야.. 그냥. gets를 이용하시던가.. scanf로 이용해서 하는 방법도 있겠고..

그리고..

get 127.0.0.1 8080 a.xxx 변수에 넘겨줄려면..

뭐 그냥 간단하게.. 토큰으로 나눠서 하면 될 것 같은데요?

strtok 함수 이용하면 되요

음 냐냐~

theageha의 이미지

get 명령어를 새로 정의한다고 해야할까요?;;

get 뒤에는 위와 같은 인자들이 따르구요.

현재는 서버 프로그램이 구동중인 WBS> 상태라서

뒤에 인자를 argv[0]등으로 못넘겨서요;; ㅎㅎ 토큰이요??;; 처..처음 들어보지만!! 지금

찾아서 해보겠습니다.^^ 답변 감사합니다~!ㅎ

----------------------------------------------------------------------------
삼인행 필유아사언(三人行 必有我師焉) - 세 사람이 길을 가면 그 중에 반드시 스승이 있다.

----------------------------------------------------------------------------
삼인행 필유아사언(三人行 必有我師焉) - 세 사람이 길을 가면 그 중에 반드시 스승이 있다.

dong1036의 이미지

음... 소스를 대충 보니깐..

열혈 하게 강의 한다는..

그 책을 참고 하신 것 같네요. ㅋ ㅋ

그리고.. 이건 태클은 아니지만... 소켓 주소 할당할때..

inet_addr 보다는.. inet_pton 을 많이 쓰지 않나요?

음 냐냐~

theageha의 이미지

음...지금..명령어 부분을 처리하지 못해서...

실제로 http 리퀘스트 하는 부분은 건들지도 못하고 있어요..ㅠ

inet_pton이요??;;; 음..제가 어제 밤새도록 열X강의를 읽었더니;;

일단은...그 소스대로만...;;

참고로 저 소스는 막 생각난대로 써논거라는....Listen 도중에 get이라는 명령어가 들어오면

client용 소켓을 하나 더 생성하고 주소와 구조체 초기화 되고, 그 소켓을 이용해서 상대방

서버와 통신을 하는거구요. get이 들어오기 전까지는 계속 accept할 준비를하구 있구요.

맞는지는 모르겠지만, 명령어 부분이 처리가 되면...ㅠㅠ이것저것 뜯어고쳐 봐야죠..

inet_pton도 찾아서 사용해보겠습니다. >_<)/

----------------------------------------------------------------------------
삼인행 필유아사언(三人行 必有我師焉) - 세 사람이 길을 가면 그 중에 반드시 스승이 있다.

----------------------------------------------------------------------------
삼인행 필유아사언(三人行 必有我師焉) - 세 사람이 길을 가면 그 중에 반드시 스승이 있다.

dong1036의 이미지

어떤 과제이길래 ㅋㅋ

저도 얼마전에 검색엔진 만든다고 HTTP 프로토콜을 아주 조금 본적이 있는데.. ㅋ ㅋ

그냥 간단하게.. 웹 문서 요청이라면야.. 간단합니다. ㅋ

음 냐냐~

theageha의 이미지

예를 들어, 프로그램1, 프로그램2 가 있습니다.

프로그램끼리는 서로 요청과 응답을 할 수 있구요...

프로그램을 실행하면

wbs> 라는 프롬프트가 나옵니다.

여기서는 두 가지 명령어만 사용가능..quit과 get

quit은 종료니까 넘어가구, get이 문제인데...

이 get 뒤에 인자가 domain name , port, filename(only .html)

즉, wbs>get localhost 8080 a.html(이미 파일이 존재)

이렇게 되면 a.html의 내용을 가져와서 화면에 뿌리는거죠....

그렇지만..며칠 째 저 인자 넘겨주는 거에서 고민하고 있다는....OTL..이제는 정말 좌절 직전..

그래서 염치없이 숙제임에도 불구하고 올린거에요..흑....

도대체 저 인자를 어떻게 잘라서 각각의 필요한 곳에 넣어야할지....

strtok 함수 찾아봤는데..C에서는 안되더라구요...공백 기준으로 짤리는 거기도 하구요...;

----------------------------------------------------------------------------

삼인행 필유아사언(三人行 必有我師焉) - 세 사람이 길을 가면 그 중에 반드시 스승이 있다.

----------------------------------------------------------------------------
삼인행 필유아사언(三人行 必有我師焉) - 세 사람이 길을 가면 그 중에 반드시 스승이 있다.

dong1036의 이미지

wbs > 상태에...

입력을.. char형으로 모두 입력을 받고

그리고.. 그것을.. strtok로 나누면 될 것 같은데요??

strtok가 C에서는 안된다는게????

www.joinc.co.kr <---여기 참고 한번 해보세요 ㅋ

음 냐냐~

dong1036의 이미지

char test[] = "get localhost 9090 a.html"
char *command;
char *ip;
char *port;
char *html;

ccommand = strtok(test. " ");
ip = strtok(NULL," ");
port = strtok(NULL, " ");
html = strtok(NULL, " ");

이런식으로 하면 될 것 같은데요??

음 냐냐~

theageha의 이미지


다른 명령을 못내리잖아요;;
예를들어 get localhost 9091 b.html 등;;

제가 잘못이해했나요?;;;
----------------------------------------------------------------------------
삼인행 필유아사언(三人行 必有我師焉) - 세 사람이 길을 가면 그 중에 반드시 스승이 있다.

----------------------------------------------------------------------------
삼인행 필유아사언(三人行 必有我師焉) - 세 사람이 길을 가면 그 중에 반드시 스승이 있다.

dong1036의 이미지

그 부분을 키보드로 입력받게 하면 되죠.. -_-;

코딩하기 귀찮아서.. 걍.. 초기화 한거죠..

음 냐냐~

theageha의 이미지

아 이렇게 기쁘고 고마울 수가 없어요..ㅠㅠ

이제는 드디어 통신 부분!!... 열심히 해보구 또 질문할게요~^^;
----------------------------------------------------------------------------
삼인행 필유아사언(三人行 必有我師焉) - 세 사람이 길을 가면 그 중에 반드시 스승이 있다.

----------------------------------------------------------------------------
삼인행 필유아사언(三人行 必有我師焉) - 세 사람이 길을 가면 그 중에 반드시 스승이 있다.

theageha의 이미지

----------------------------------------------------------------------------
삼인행 필유아사언(三人行 必有我師焉) - 세 사람이 길을 가면 그 중에 반드시 스승이 있다.

----------------------------------------------------------------------------
삼인행 필유아사언(三人行 必有我師焉) - 세 사람이 길을 가면 그 중에 반드시 스승이 있다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.