프로그래밍

 3198, 1/160 회원가입  로그인  
   qaz4564
   c++ 소켓프로그래밍

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


귀찮으시더라도 도와주세요 ㅜㅜ 몇일이 걸렸습니다.

프로젝트 속성에 [링커]>[입력]>[추가종속성]>ws2_32.lib를 하고 컴파일을 하였습니다.
server 소스
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <Windows.h>
#include <process.h>
#include <string.h>
#define BUFSIZE 512
HANDLE hthread;  //  쓰레드를 제어 하기위한 핸들
SOCKET client_sock;  // 통신용 소켓
static unsigned WINAPI re()// 메세지를 보내기 위한 함수
{
  SOCKADDR_IN clientaddr;//클라이언트주소
  int addrlen;
  char buf[BUFSIZE+1];
  int retval;
  addrlen = sizeof(clientaddr);
  SOCKET listen_sock = socket(AF_INET, SOCK_STREAM, 0);
  accept(listen_sock,(SOCKADDR *) &clientaddr, &addrlen);

//  데이터 받기
  do{
   ZeroMemory(buf, sizeof(buf));
   retval = recv(client_sock, buf, BUFSIZE, 0);
   if(retval == 0)
   return 0;
  
   // 받은 데이터 출력
   if(retval != -1){
   buf[retval] = '\0';
   printf("\n[TCP/%s:%d]%d받앗습니다 %s\n[보낼 데이터]",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port),retval, buf);
   }
  }while(1);
}
int main(int argc, char* argv[])
{
  int retval;
  // 윈속 초기화
  WSADATA wsa;
  if(WSAStartup(MAKEWORD(2,2), &wsa) != 0)
  return -1;

  // socket(tcp/ip를 이용(af주소체계),tcp방식의 스트림, 특정프로토콜설정인수 대부분0이다)
  SOCKET listen_sock = socket(AF_INET, SOCK_STREAM, 0);// 소켓만들기

  // bind() bind란 서버의 아이피,포트 를 부여하는것
  SOCKADDR_IN serveraddr;
  ZeroMemory(&serveraddr, sizeof(serveraddr));
  serveraddr.sin_family = AF_INET;//도매인
  serveraddr.sin_port = htons(9000);
  serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); //IPv4에서는 INADDR_ANY(와일드카드) 이고 이것으로 아이피를 받아온다
  bind(listen_sock, (SOCKADDR *)&serveraddr,sizeof(serveraddr));  
//    소켓     주소   크기
  // listen()
  listen(listen_sock, SOMAXCONN);//클라이언트 대기 상태를 만듬 ,
         //두번쨰 매개변수 가  백로그 라는것이고 대기가능한 최대 연결갯수(넘으면 요청거절)

  // 데이터 통신에 사용할 변수
  SOCKADDR_IN clientaddr;//클라이언트주소
  int addrlen;
  char buf[BUFSIZE+1];
  while(1){
   //accept()
  addrlen = sizeof(clientaddr);
  client_sock = accept(listen_sock,(SOCKADDR *) &clientaddr, &addrlen);//클리아언터에 대한 정보를 클라이언트소켓에 너음
                   //반환값 : 연결된소켓, 클라이언트의 주소, 그것의 길이
   printf("\n[TCP 서버] 클라이언트 접속: IP 주소=%s, 포트 번호=%d\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
    unsigned id;
  // 쓰레드 만들고 받는 함수를 쓰레드에서 함수를 호출한다
    //create 함수도 있지만 c++/c 에서는 동작이 잘 되지 않는다.
    hthread = (HANDLE)_beginthreadex(NULL,0,(unsigned int (__stdcall*)(void*))re,NULL,0,&id);
  
    if(hthread ==0)
     puts("_beginthreadex error");
  
   // 클라이언트와 데이터 통신
   while(1){
      // 데이터 통신에 사용할 변수
   int len;
   // 서버와 데이터 통신
   // 데이터 입력
   ZeroMemory(buf, sizeof(buf));// buf를 비워준다 초기화
   printf("\n[보낼 데이터]");
   if(fgets(buf, BUFSIZE+1, stdin) == NULL)
   break;
   // '\n' 문자 제거
   len = strlen(buf);
   if(buf[len-1] == '\n')
   buf[len-1] = '\0';
   if(strlen(buf) == 0)
   break;
  
   retval = send(client_sock, buf, strlen(buf), 0); //보내는 함수 ,반환값은 바이트 수
  
   printf("[TCP 서버] %d바이트를 보냈습니다.\n", retval);
   }
  closesocket(client_sock);
  printf("[TCP 서버] 클라이언트 종료: IP 주소=%s, 포트 번호=%d\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
  }
  closesocket(listen_sock);
  // 윈속 종료
  WSACleanup();
  return 0;
}



//////////////////////////////////////////////////////////////

client 소스
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#define BUFSIZE 512
int main(int argc, char* argv[])
{
int retval;
int ret;
// 윈속 초기화, 소캣 초기화
WSADATA wsa;
if(WSAStartup(MAKEWORD(2,2), &wsa) != 0)
return -1;
// socket()
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);// 소켓만들기
// connect() 서버로 연결
SOCKADDR_IN serveraddr;
serveraddr.sin_family = AF_INET; // TCP/IP를 사용
serveraddr.sin_port = htons(9000);
serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");//서버의 IP 주소
retval = connect(sock, (SOCKADDR *)&serveraddr,sizeof(serveraddr));


SOCKADDR_IN clientaddr;//클라이언트주소
  int addrlen;
// 데이터 통신에 사용할 변수
char buf[BUFSIZE+1];
int len;
// 서버와 데이터 통신
while(1){
  addrlen = sizeof(clientaddr);
  SOCKET n_sok;
  
// 데이터 입력
ZeroMemory(buf, sizeof(buf));
printf("\n[보낼 데이터]");
if(fgets(buf, BUFSIZE+1, stdin) == NULL)
  break;
// '\n' 문자 제거
len = strlen(buf);
if(buf[len-1] == '\n')
buf[len-1] = '\0';
if(strlen(buf) == 0)
  break;
// 데이터 보내기
retval = send(n_sok, buf, strlen(buf), 0);
printf("[TCP 클라이언트] %d바이트를 보냈습니다.\n", retval);
// 데이터 받기
ZeroMemory(buf, sizeof(buf));
ret = recv(n_sok, buf, BUFSIZE, 0);

if(ret == 0)
break;
// 받은 데이터 출력
buf[ret] = '\0';
printf("[TCP 클라이언트] %d바이트를 받았습니다.\n", ret);
printf("[받은 데이터] %s\n", buf);
}
  // closesocket()
closesocket(sock);
// 윈속 종료
WSACleanup();
return 0;
}


서로 문자열을 주고 받는 통신 프로그램 입니다.
데이터를 보낼 때는 서버든 클라이언트든 먼저 가능하고, 클라이언트는 데이터를 보내야 받기가 가능 합니다.
문제는 한 컴퓨터에서는 잘 되지만 서로 다른 컴퓨터에서 클라이언트에 있는 IP주소를 서버 컴퓨터에 맞게 변경 후  서버와 클라이언트를 각각 실행 시키면 동작하지 않습니다.
무엇이문제일까요 도와주세요

  Hit : 8489     Date : 2015/01/14 05:25