TCP/IP 소켓프로그래밍 공부 중 질문이 있습니다. 클라이언트가 서버없이도 작동하는데 어떻게 된 일이죠?
글쓴이: qeeeeep / 작성시간: 월, 2016/02/15 - 11:43오전
안녕하세요 TCP/IP 소켓 프로그래밍을 공부하는 학생입니다.
이제 막 서버소켓과 클라이언트소켓을 TCP 형식으로 만들어 연결하는 것을 공부하였습니다.
연습 예제로 윈도우즈10 콘솔환경에서 클라이언트가 사용자에게 문자열을 입력받아 서버로 보낸 뒤
서버는 그 문자열을 다시 클라이언트로 보내고 클라이언트가 그것을 출력하는 에코 서버-클라이언트 소켓을
만들고 있었습니다.
그런데 이렇게 만든 예제를 실행할 때 클라이언트의 에러핸들링함수를 만들지 않으면
서버를 실행하지 않아도 클라이언트가 정상작동되는 현상을 발견하였습니다.
연결한 소켓으로부터 데이터를 수신하는 recv()함수가 작동하는 것입니다.
이것이 정상적인 상황인건가요? 왜 이런 현상이 발생하는지 궁금합니다.
첨부파일은 실행 결과 스크린샷 입니다.
아래는 서버소스입니다.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h> #define BUF_SIZE 1024 void ErrorHandling(char *message); int main(int argc, char *argv[]) { WSADATA wsaData; SOCKET hServSock, hClntSock; char message[BUF_SIZE]; int strLen, i; SOCKADDR_IN servAdr, clntAdr; int clntAdrSize; if(argc != 2) { printf("Usage : %s <port>\n", argv[0]); exit(1); } if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0) ErrorHandling("WSAStartup() error!"); hServSock=socket(PF_INET, SOCK_STREAM, 0); if(hServSock==INVALID_SOCKET) ErrorHandling("socket() error"); memset(&servAdr, 0, sizeof(servAdr)); servAdr.sin_family=AF_INET; servAdr.sin_addr.s_addr=htonl(INADDR_ANY); servAdr.sin_port=htons(atoi(argv[1])); if(bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr))==SOCKET_ERROR) ErrorHandling("bind() error"); if(listen(hServSock, 5)==SOCKET_ERROR) ErrorHandling("listen() error"); clntAdrSize=sizeof(clntAdr); for(i=0;i<5;i++) { hClntSock=accept(hServSock, (SOCKADDR*)&clntAdr, &clntAdrSize); if(hClntSock==-1) ErrorHandling("accept() error"); else printf("connected client %d \n", i+1); while((strLen=recv(hClntSock, message, BUF_SIZE, 0))!=0) send(hClntSock, message, strLen, 0); closesocket(hClntSock); } closesocket(hServSock); WSACleanup(); return 0; } void ErrorHandling(char* message) {}
다음은 클라이언트 소스입니다.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h> #define BUF_SIZE 1024 void ErrorHandling(char*); int main(int argc, char *argv[]) { WSADATA wsaData; SOCKET hSocket; char message[BUF_SIZE]; int strLen; SOCKADDR_IN servAdr; if(argc!=3) { printf("Usage: %s <IP> <port>\n", argv[0]); exit(1); } if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0) ErrorHandling("WSAStartup() error!"); hSocket=socket(PF_INET, SOCK_STREAM, 0); if(hSocket==INVALID_SOCKET) ErrorHandling("socket() error"); memset(&servAdr, 0, sizeof(servAdr)); servAdr.sin_family=AF_INET; servAdr.sin_addr.s_addr=inet_addr(argv[1]); servAdr.sin_port=htons(atoi(argv[2])); if(connect(hSocket, (SOCKADDR*)&servAdr, sizeof(servAdr))==SOCKET_ERROR) ErrorHandling("connect() error"); else puts("connected......."); while(1) { fputs("Input message(Q to quit): ", stdout); fgets(message, BUF_SIZE, stdin); if(!strcmp(message,"q\n") || !strcmp(message,"Q\n")) break; send(hSocket, message, strlen(message), 0); strLen=recv(hSocket, message, BUF_SIZE-1, 0); message[strLen]=0; printf("message from server: %s", message); } closesocket(hSocket); WSACleanup(); return 0; } void ErrorHandling(char * message) {}
File attachments:
첨부 | 파일 크기 |
---|---|
echo_ghost.png | 10.09 KB |
Forums:
지금 얼핏 봤을땐..
while(1) 안에서...
message 버퍼에다가 입력 받은 후에.
recv 함수 호출 후에 strLen 값 한번 찍어 보세요....
그 바로 밑에서
message값 그거 그대로 찍고 있으니까요.... 똑같이 나오는거 같은데..
지금 컴파일 할 수 없는 환경이라 제가 테스트를 못하겠네요.
아아!
send하려고 입력한 배열메모리를 다시 출력하고 있었기 때문이었네요!! 감사합니다!!
음 ..
connect 가 정상적으로 수행되었다면 화면에 "connected....." 가 출력되었겠죠?
connect() 가 이미 실패했기 때문에, 거기서 종료했어야 하는데.. 그냥 계속 진행하셨네요.
그 이후의 내용은 그냥 수행되서는 안 되는 코드가 수행된 것일 뿐 아무런 의미가 없습니다.
거기에 socket 이 connect 되지도 않았는데 recv() 를 했으니, strLen 에는 -1 이 리턴되었을 텐데..
어쨌든 recv() 가 에러를 리턴한 상황에서도 그걸 무시하고, 위험하게 message[-1] 에 0 을 집어넣었을 뿐만 아니라..
그냥 message 를 출력해 버렸으니.. 처음에 입력받은 message 의 내용이 고스란히 출력될 수 밖에 없겠죠.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
아하..
그렇네요.. 보낼때 입력한 메시지와 같은 메모리를 다시 출력했었기 때문이네요..;; 감사합니다!!
댓글 달기