구조체 맴버필드의 값을 표준입력으로 받아 전달하려고합니다.
글쓴이: ssif / 작성시간: 월, 2005/07/18 - 6:19오전
서버쪽 구조체와 클라이언트 구조체를 다음과 같이 전역으로 선언했습니다.
struct login { char lin[LOGIN_LIN]; char login_id[LOGINBUF]; char login_pw[LOGINBUF]; };
클라이언트에서 다음과 같은 함수를 통해 구조체 맴버필드에 대입을 하려고 합니다.fgets()를 사용했습니다.
int input_id_pw(void) { int input_status=0; printf("%d\n",input_status); fputs("아이디와 비밀번호를 입력하세요.\n",stdout); fputs("ID :",stdout); fgets(Login.login_id,LOGINBUF,stdin); printf("\n id: %s \n",Login.login_id); if(strlen(Login.login_id)>0) { input_status++; } printf("%d\n",input_status); fputs("PW :",stdout); fgets(Login.login_pw,LOGINBUF,stdin); printf("\n pw: %s \n",Login.login_pw); if(strlen(Login.login_pw)>0) { input_status++; } printf("%d\n",input_status); printf("아이디와 비밀번호를 확인중입니다.\n"); return input_status; }
이것을 다음과 같이 해서 send()로 서버에 보냈습니다.
while(1) { if(status==0) { status_t=input_id_pw(); if(status_t==2) { strncpy(Login.lin,"lin",3); printf("\n id: %s \n",Login.login_id); printf("\n pw: %s \n",Login.login_pw); send(hSocket,(void *)&Login,sizeof(Login),0); } ........(중략)
서버에서는 다음과 같이 받았습니다.
memset(&Login,0,sizeof(Login)); while((strLen=recv(hClntSock,(void *)&Login,sizeof(Login),0)) !=0) { printf("%s\t,%s\t,%s\n",Login.lin,Login.login_id,Login.login_pw);
서버의 콘솔화면에서 출력되는 값은 다음과 같이 나옵니다.
lin , , , ,
정확히 출력되는 부분은 strncpy(Login.lin,"lin",3); 로 해서 보낸 구조체의 첫번째 맴버필드 뿐입니다.나머지 부분은 공백으로 나옵니다.또한 왜 두번 연달아 출력되는지 잘 모르겠습니다.fgets()로 클라이언트 구조체의 맴버필드에 저장했는데 서버에서 확인되는 값은 첫번째 맴버필드뿐입니다. 무엇이 잘못된것 인지 잘 모르겠습니다.사용한 환경은 윈도우버전 devcpp 4.9.9.2의 gcc컴파일러와 ide입니다.미리 감사드립니다.
Forums:
1. struct를 네트워크를 통해 그대로 보내는 것은 바람직하지 않을
1. struct를 네트워크를 통해 그대로 보내는 것은 바람직하지 않을 것 같습니다. struct의 데이터 패딩을 처리하는 방식이 기기간에 다를 수 있기 때문입니다.
2. send() 하신 후 에러를 체크하시는 것이 좋을 것 같습니다.
3. recv() 함수는 non-blocking 소켓인 경우, 읽을 데이터가 없으면 -1을 반환하고 errno를 설정하고, blocking 소켓인 경우에는 데이터가 올 때까지 기다립니다. 어떤 유형의 소켓을 사용하셨는지 궁금하네요.
4. 어떤 유형의 소켓을 사용했던, recv()는 요청한 데이터 크기만큼이 다 찰 때까지 기다리기 보다는, 읽을 데이터가 있으면 최대 요청한 크기까지 데이터를 버퍼에 복사하고 읽은 데이터의 숫자를 반환하는 것이 보통입니다. 따라서 전체 데이터가 다 올 때까지 루프를 돌면서 읽어야 합니다.
5. 님께서 사용하신 읽기 코드 중,
의 경우 recv()에서 에러가 발생한 경우에도 아래로 진입하게 되는 문제가 있습니다.
6. 따라서 struct를 서버와 클라이언트 양쪽에서 동일하게 처리하고, send()가 모든 데이터를 정상적으로 보냈으며, recv()에서 사용하는 소켓이 blocking 소켓이라고 가정하면 다음과 같은 형태로 구성하시는 것을 어떨까요?
님께서 써주신 글을 잘보았습니다. 실은 님께서 쓰신 글을 보기전 다른 방
님께서 써주신 글을 잘보았습니다. 실은 님께서 쓰신 글을 보기전 다른 방향으로선회를 했었습니다.즉 구조체 자체를 보내는 것이 아니라 구조체의 맴버 필드를 보내는것이 조금더 좋아보였기 때문입니다.참고한 글은 http://bbs.kldp.org/viewtopic.php?p=271688#271688 입니다.그러나 같은 문제가 여전히 발생했습니다.제가짠 소스를 보면서 파악한 문제점은 여전히 서버쪽에서 패킷(혹은 보내어진 데이터)를 모두 다 받지 못한다는 것이었습니다.(물론 클라이언트에서도 문제가 있을수도 있습니다.)
이 문제를 해결 하기 위해서 님께서 보여주셨던 예를 사용해보았으나 아직까지는 만족하지 못하고 있습니다.서버쪽에서 받은 데이터를 버퍼에서 다 받을수 있는 방법에 대해서 조금더 설명해주셨으면 합니다.이부분에 대해서 님의 소스를 보고 로직은 이해를 했으나 제가 아직 잘 이해를 못하는것 같습니다.
소켓은 다음과 같이 생성했습니다.
이렇게 사용하면 blocking형 이라고 알고 있습니다.
봄들판에서다
댓글 달기