프로그래밍

 3198, 1/160 회원가입  로그인  
   whtjdwls151
   TCP/IP 소켓 프로그래밍 오류

http://www.hackerschool.org/HS_Boards/zboard.php?AllArticle=true&no=6365 [복사]


안녕하세요

TCP/IP로 프로그램 만들다가 잘 안되는 부분이 있어서 질문드립니다.

저는 C언어로 구현하려고 합니다.

제가 한 프로그램이 서버와 클라이언트 역할을 하는 코드를 구현 해야하는데요



코드순서

/*

client 소켓 변수= hSocket

server 소켓 변수= hServSock

들어올 client 소켓 변수= hClntSock 라고 합시다.

*/

socket(hClntSock에 파일디스크립터 할당)-connect(다른 프로그램에게 연결 요청)-socket(hServSock에 파일디스크립터 할당)-bind(주소정보할당)-listen(대기)-accept(클라이언트 연결 요청 수락)



이렇게 구현하면, 양방향으로

다른 프로그램1 -> 지금설명한 프로그램 -> 다른 프로그램2



이렇게 되지 않나요?

책에서는 이렇게 구현된다고 본적이 있는 거 같아서 구현해 보았습니다

아래는 제가 구현한 코드입니다.
그런데 오류가 발생하네요.

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h>

#define BUF_SIZE 1024

int main(void)
{
  WSADATA wsaData;
  SOCKET hSocket, hServSock, hClntSock;

/*

client 소켓 변수= hSocket

server 소켓 변수= hServSock

들어올 client 소켓 변수= hClntSock 라고 합시다.

*/
  char message[BUF_SIZE];
  int strLen;
  SOCKADDR_IN servAdr, servAdrs, clntAdr;

int clntAdrSize;

if(WSAStartup(MAKEWORD(2, 2), &wsaData)!=0)
  {
   printf("에러 메세지 : 라이브러리 초기화 실패\n\n");
   printf("잠시후 다시 실행해주세요^^;;");
   Sleep(5000);
   exit(1);
  }

hSocket=socket(PF_INET, SOCK_STREAM, 0);
  if(hSocket==INVALID_SOCKET)
  {
   printf("에러 메세지 : 소켓 생성 실패\n\n");
   printf("잠시후 다시 실행해주세요^^;;");
   Sleep(5000);
   exit(1);
  }

memset(&servAdr, 0, sizeof(servAdr));
  servAdr.sin_family=AF_INET;
  servAdr.sin_addr.s_addr=inet_addr("127.0.0.1");
  servAdr.sin_port=htons(atoi("9190"));

if(connect(hSocket, (SOCKADDR*)&servAdr, sizeof(servAdr))==SOCKET_ERROR)
  {
   printf("에러 메세지 : 연결 실패\n\n");
   printf("잠시후 다시 실행해주세요^^;;");
   Sleep(5000);
   exit(1);
  }

hServSock=socket(PF_INET, SOCK_STREAM, 0);
  if(hServSock==INVALID_SOCKET)
  {
   printf("에러 메세지 : 소켓 생성 실패\n\n");
   printf("잠시후 다시 실행해주세요^^;;");
   Sleep(5000);
   exit(1);
  }

memset(&servAdrs, 0, sizeof(servAdrs));
  servAdrs.sin_family=AF_INET;
  servAdrs.sin_addr.s_addr=htonl(INADDR_ANY);
  servAdrs.sin_port=htons(atoi("9190"));

if(bind(hServSock, (SOCKADDR*)&servAdrs, sizeof(servAdrs))==SOCKET_ERROR)
  {
   printf("에러 메세지 : 주소 정보 할당 실패\n\n");
   printf("잠시후 다시 실행해주세요^^;;");
   Sleep(5000);
   exit(1);
  }

if(listen(hServSock, 5)==SOCKET_ERROR)
  {
   printf("에러 메세지 : 연결 요청 대기 실패\n\n");
   printf("잠시후 다시 실행해주세요^^;;");
   Sleep(5000);
   exit(1);
  }

clntAdrSize=sizeof(clntAdr);

hClntSock=accept(hServSock, (SOCKADDR*)&clntAdr, &clntAdrSize);
  if(hClntSock==-1)
  {
   printf("에러 메세지 : 접속 실패\n\n");
   printf("잠시후 다시 실행해주세요^^;;");
   Sleep(5000);
   exit(1);
  }
  else
  {
    이 부분은 나중에 제가 프로그램 용도에 맞게 코딩할거예요...ㅎ
  }

closesocket(hSocket);
  closesocket(hServSock);
  closesocket(hClntSock);
  WSACleanup();
  return 0;
}

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




왜 오류가 뜨는거죠ㅠㅠ


도와주세요.

  Hit : 8839     Date : 2013/07/13 03:37



    
rainroad87 에러 내용을 올려주시면 해결에 도움이 됩니다. 2013/07/15  
rainroad87 생각해 볼건 2가지가 있겠네요

윈속을 사용하셨으니 vs로 컴파일 하셨으리라 생각 되는데

#include "stdafx.h" 를 추가하지 않으셨든가

윈속의 라이브러리를 링크하지 않으셨든가

둘중 하나로 판단됩니다.

첫번째 문제의 경우 단순히 #include "stdafx.h"를 맨 위에 선언해주시면 해결이 가능하고

두번째 문제일 경우 해당 프로젝트의 옵션을 변경해주시든지

아니면 소스내에서 #pragma comment(lib, "ws2_32.lib") 를 추가하면 해결되리라 생각됩니다.

제가 2가지를 적용시켜서 컴파일해본 결과 vs2005기준에서는 컴파일에러없이 실행되는것을 확인하였습니다
2013/07/15  
rainroad87 그리고 소스 부분에서 논리적 오류가 있는데 connect와 accept가 쌍이 됩니다.

한마디로 서버에서는 소켓을 생성하고 바인드로 설정한후 리슨을 호출하여야만

클라이언트의 연결요청을 accept를 통해 받아들이는데

서버가 제대로 가동되지도 않은 상태에서 connect를 호출하게 되어 있네요.

그리고 listen의 경우 동기 함수입니다. listen을 호출하고 그 밑에 connect를 호출한다 해도

프로세스의 실행 흐름은 누군가가 connect를 하기 전에는 listen 을 넘어갈수가 없습니다.

서버 프로그램과 클라이언트 프로그램을 따로 작성하시거나, 스레드를 통하여 제어하셔야 할거 같습니다.

그리고 실행중인 다른 프로세스와 무언가를 하려 할때는 , IPC를 주로 사용하니 한번 사용해 보시기 바랍니다.

검색을 위한 키워드를 남기자면 메일슬롯, 파이프, 네임드 파이프 등이 있습니다.

그럼 즐거운 프로그래밍 되시길 바랍니다.
2013/07/15