cin.getline에서 공백 값이 들어갑니다...

balgarac1의 이미지

프로그램의 구조는 클라이언트와 서버에서 프로토콜을 주고 받는 형식입니다.

간단하게 메세지 형식을 보여드리면

#define UB2 unsigned short
#define UB4 unsigned int
#define SCHAR signed char
 
#define auth_req_msg 1
#define auth_res_msg 2
#define sql_req_msg 3
#define sql_res_msg 4
#define close_req_msg 5
#define close_res_msg 6
 
 
#define SELECT 1
#define UPDATE 2
#define DELETE 3
 
typedef struct _dgt_auth_req_msg
{
	UB2 msg_type;
	SCHAR db_user[33];
	SCHAR password[33];
	SCHAR program_name[63];
	SCHAR db_name[33];
}dgt_auth_req_msg; 
 
typedef struct _dgt_auth_res_msg
{
	UB2 msg_type;
	UB2 rtn_len;
	SCHAR rtn_msg[257];
}dgt_auth_res_msg; 
 
typedef struct _dgt_sql_req_msg
{
	UB2 msg_type;
	UB4 sql_len;
	SCHAR sql_text[1025];
	UB2 sql_type;
}dgt_sql_req_msg; 
 
typedef struct _dgt_sql_res_msg
{
	UB2 msg_type;
	UB4 rtn_len;
	SCHAR rtn_data[1025];
	UB2 sql_type;
}dgt_sql_res_msg; 

이렇게 되어 있습니다.

클라이언트에서 _dgt_auth_req_msg 메세지를 보내면 서버에서는 _dgt_auth_res_msg 를 보냅니다.

잘 안풀리는 점은 서버와 클라이언트에서 로그인 처리를 하고 메세지를 주고 받는 처리를 할 때 생깁니다.

클라이언트 쪽에서

	cout << "ID:";
	cin >> req.db_user;
	cout << "Password:";
	cin >> req.password;
	cout << "DB Name:";
	cin >> req.db_name;
 
	strcpy((char *)req.program_name, "simpleDB_Client");
	// cout << "program name:" << req.program_name << endl;
 
	req.msg_type = auth_req_msg; // set msg type 1
 
	send(m_nSock, (void *)&req, sizeof(req), 0); // msg type 1 send to proxy
	//// block ////
 
 
	///////////////////////////////////////////recv///////////////////////////////////////////////
 
 
	int a_resLen = sizeof(dgt_auth_res_msg);
	cout << "resLen size : " << a_resLen << endl;
 
	int a_recvCnt = 0;
	int a_strLen;
 
	memset(m_pbuf, sizeof(m_pbuf), 0);
	while(a_recvCnt < a_resLen)
	{
		a_strLen = recv(m_nSock, m_pbuf + a_recvCnt, BUFSIZ, 0);
		if(a_strLen == -1)
		{
			perror("net_Login () error");
		}
		a_recvCnt += a_strLen;
		// cout <<"in while loop recv..." << endl;
	}
 
	res = *(dgt_auth_res_msg *)m_pbuf; // buf to dgt_auth_res_msg
 
	if(res.msg_type != auth_res_msg)
		perror("net_LogIn Wrong Message Pakcet..");
	else
	{
		cout << res.rtn_msg << endl;
		int nRet = net_DBquery();
		if(nRet < 0)
			return -1;
	}

아이디와 패스워드 등을 입력받고 메세지를 채워서 서버로 보냅니다. 서버는 제대로 된 메세지가 왔는지 확인하고 응답 메세지를 보냅니다.

그 후에 쿼리문을 입력 받아서 서버와 메세지를 주고 받을 때 입력하지도 않은 공백값이 들어가서 서버로 전송됩니다..

 CNetwork::net_DBquery ()
{
	///////////////////////////send sql////////////////////////////////
 
	while(true)
	{
		cout << "SQL >";
		cin.getline((char *)sqlReq.sql_text, 1024, '\n');
 
		//cin.getline((char *)sqlReq.sql_text, 1024);
 
		if(!strcmp("exit", (const char *)sqlReq.sql_text))
			return -1;
 
		sqlReq.msg_type = sql_req_msg; // set sql message type
		strcpy(m_chSqlText, (const char *)sqlReq.sql_text);
		sprintf(m_chSqlType, "%s", m_chSqlText);
 
		m_nRetType = net_sqlTypeCheck (m_chSqlType);
 
		sqlReq.sql_type = m_nRetType; // set sql type
		sqlReq.sql_len = strlen((const char *)sqlReq.sql_text); // sql len
		// cout << sqlReq.sql_text << endl; // print message
 
		send(m_nSock, (void *)&sqlReq, sizeof(sqlReq), 0);
		/// block ///
 
 
    //////////////////////////////////recv sql///////////////////////////////
		int resLen = sizeof(dgt_auth_res_msg);
		memset(m_pbuf, sizeof(m_pbuf), 0);
 
		while(m_recvLen < resLen)
		{
			// cout << "DB_Query recv error1."<< endl;
			m_recvCnt = recv(m_nSock, m_pbuf + m_recvLen, BUFSIZ, 0);
			if(m_recvCnt == -1)
				perror("net_DBquery () recv error..");
 
			m_recvLen += m_recvCnt;
			// cout << "DB_Query recv error2." << endl;
		}
 
		sqlRes = *(dgt_sql_res_msg *)m_pbuf; // buf to dgt_sql_res_msg
 
		if(sqlRes.msg_type != sql_res_msg)
		{
			cout << "sql msg type:" << sqlRes.msg_type << endl;
			perror("net_DBquery () wrong response packet..");
			continue;
		}
 
		cout << "Result:" << sqlRes.rtn_data << endl;
	 }
	return 1;
}


제 생각에 cin.getline이 문제인 것 같은데 다르게 바꿔보아도 잘 고쳐지지가 않아서 질문을 남깁니다.
질문 내용이 길지만 가르쳐주시면 감사하겠습니다..

balgarac1의 이미지

cin.getline이 논블럭 함수인거 같네요...

shint의 이미지

6시간 걸려서 만들었습니다. 참고해보세요.
윈도우XP 32비트. DevC++ 을 사용했습니다.
컴파일 할때는. 압축파일을 바탕화면에 풀어놓고. DevC++의 프로젝트 옵션에서 라이브러리 경로만 변경해주시면 될겁니다.
DevC++은 버전이 2가지니. 주의하시기 바랍니다.

그리고. 각종 오류가 났었던. 정보를 함께 추가했습니다.

댓글 첨부 파일: 

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.