디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

일대일 채팅 누가 물어봤지?

로또로(218.39) 2012.01.25 21:30:00
조회 211 추천 0 댓글 0


// SocketClient.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

 

#include "stdafx.h"
#include "winsock.h"
#include <process.h>

#define MAXBUF 60
#define MAXLINE 15
#define PORT 9000
#define IPADDR "127.0.0.1"  // server IP

CRITICAL_SECTION hCriticalSection;   // 동기화 도구 - 크리티컬 섹션 변수

int curLine = 0;       // dialog 배열의 현재 위치
char dialog[MAXLINE][MAXBUF+1+12] = {0, }; // 대화내용 저장
bool isDisconnected = false;    // 연결이 끊어졌는지 체크
char bufBlank[MAXBUF+1+12];     // 콘솔창에서 1라인을 지우기 위한 공백텍스트임

void show_dialog();       // 대화내용을 보여주는 변수
unsigned int WINAPI RecvThreadProc(LPVOID lpParam);
unsigned int WINAPI SendThreadProc(LPVOID lpParam);

 

int main()
{
 SOCKET c_socket;
 struct sockaddr_in client_addr;
 WORD wVersionRequested;
 WSADATA wsaData;
 int err;
 char addr[] = "000.000.000.000";

 DWORD dwRecvThreadId, dwSendThreadId;
 HANDLE hRecvThread, hSendThread;

 InitializeCriticalSection(&hCriticalSection);  // 동기화 도구 초기화 함.

 memset(dialog, 0, sizeof(dialog));
 memset(bufBlank, (int)' ', sizeof(bufBlank));  // space로 채운다. 화면을 지우기 위한것.
 bufBlank[ sizeof(bufBlank)-1 ] = '\0';

 // before use socket, must do startup! 소켓 초기화
 wVersionRequested=MAKEWORD(2,2);
 err = WSAStartup(wVersionRequested, &wsaData);

 [...];  // 전체 화면 지우기


 // 연결할 서버 주소를 입력 받는다.
 printf("\n\n * Input IP address : ");
 fflush(stdin);
 scanf_s("%s", addr, sizeof(addr));

 c_socket = socket(PF_INET, SOCK_STREAM,0);  // 소켓 생성


 memset(&client_addr, 0, sizeof(client_addr)); // 주소 구조체 셋팅
 client_addr.sin_addr.s_addr = inet_addr(addr);
 client_addr.sin_family = AF_INET;
 client_addr.sin_port = htons(PORT);

 // connect, 연결함
 if(connect(c_socket, (struct  sockaddr *) &client_addr, sizeof(client_addr)) == -1)
 {
  printf("Can not connect\n");
  closesocket(c_socket);
  return -1;
 }

 printf("\n * Connected ...\n");

 Sleep(1000);

 [...];

 isDisconnected = false;

 // 서버로 부터 데이터를 기다리는 쓰레드 생성
 hRecvThread = (HANDLE)_beginthreadex(NULL, 0, RecvThreadProc, (void*)c_socket, CREATE_SUSPENDED, (unsigned*)&dwRecvThreadId);

 // 서버로 데이터를 보내는 쓰레드 생성
 hSendThread = (HANDLE)_beginthreadex(NULL, 0, SendThreadProc, (void*)c_socket, CREATE_SUSPENDED, (unsigned*)&dwSendThreadId);

 ResumeThread(hRecvThread);  // 쓰레드 시작
 ResumeThread(hSendThread);  // 쓰레드 시작
 WaitForSingleObject(hRecvThread, INFINITE);  // 쓰레드가 종료될때까지 대기
 WaitForSingleObject(hSendThread, INFINITE);  // 쓰레드가 종료될때까지 대기

 // disconnect,  두 쓰레드가 모두 종료되면, 소켓을 닫음.
 closesocket(c_socket);  

 // 동기화 도구 해제
 DeleteCriticalSection(&hCriticalSection);

 return 0;
}

 

 

// 콘솔에서 대화 내용등을 보여주는 일을 함
void show_dialog()
{
 HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 윈도우 핸들 얻기

 DWORD  dw;
 COORD  Coor;
 int i=0, line = 0;

 Coor.X=1;
 for(i=0; i<MAXLINE; i++) // 대화내용을 콘솔의 아래쪽부터 한줄씩 위로 표시함
 {
  // set position. 위치 설정
  Coor.Y = MAXLINE - i;
  line = (curLine + MAXLINE - i) % MAXLINE;

  // 먼저 기존의 대화 내용을 지우고,
  WriteConsoleOutputCharacterA(hOut,bufBlank,strlen(bufBlank),Coor,&dw);

  // 대화내용을 표시해줌
  WriteConsoleOutputCharacterA(hOut,dialog[line],strlen(dialog[line]),Coor,&dw);
 }

 if(isDisconnected) // 연결이 끊어졌을때,
 {
  char disc[] = "* Disconnected.. Press Enter key.. ";
  Coor.X = 1;
  Coor.Y = MAXLINE + 1;
  WriteConsoleOutputCharacterA(hOut,disc,strlen(disc),Coor,&dw);
 }
}


// 수신 쓰레드
unsigned int WINAPI RecvThreadProc(LPVOID lpParam)
{
 SOCKET c_socket = (SOCKET)lpParam;
 int n;
 char rcvBuffer[MAXBUF+1] = {0, };

 // receive data from server
 while(1)
 {
  // 먼저 연결이 끊어 졌는지 체크, isDisconnected 가 TRUE 이면 내가 접속을 끊은것이고,
  // recv 리턴값이 0 이면 상대방이 접속을 끊은것이다. 0보다 작으면 다른 에러 발생으로 종료된것
  if(isDisconnected || (n = recv(c_socket, rcvBuffer,sizeof(rcvBuffer), 0)) <= 0)
  {
   closesocket(c_socket); // 소켓을 닫고

   if(isDisconnected == true)
   {
    return 0;
   }
   isDisconnected = true;

   EnterCriticalSection(&hCriticalSection);
   show_dialog();
   LeaveCriticalSection(&hCriticalSection);
   return (-1);
  }
  rcvBuffer[n] = '\0';

  // 수신된 내용을 대화내용 저장 배열에 카피하고 표시함.
  EnterCriticalSection(&hCriticalSection);
  memset(dialog[curLine], 0, sizeof(dialog[curLine]));
  strcpy(dialog[curLine], "Remote : ");
  strcat(dialog[curLine], rcvBuffer);
  show_dialog();

  curLine = (curLine + 1) % MAXLINE;
  LeaveCriticalSection(&hCriticalSection);
 };

 return 0;
}

// 발신 쓰레드
unsigned int WINAPI SendThreadProc(LPVOID lpParam)
{
 SOCKET c_socket = (SOCKET)lpParam;
 int n;
 char sendBuffer[MAXBUF+1] = {0, };
 HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
 DWORD  dw;
 COORD cdPos = { 0, MAXLINE + 3 };
 COORD cdPos2 = { 0, MAXLINE + 4};

 // send chat text
 while(1)
 {
  memset(sendBuffer, 0, sizeof(sendBuffer));

  // 기존의 사용자 입력 내용을 삭제하고,
  WriteConsoleOutputCharacterA(hOut,bufBlank,strlen(bufBlank),cdPos2,&dw);

  // scanf 입력 받은 후 콘솔이 아래로 내려 가지 않도록 위치를 고정시킴
  SetConsoleCursorPosition(hOut, cdPos);

  if(isDisconnected)
  {
   closesocket(c_socket);
   return 0;
  }

  // 슬래쉬 exit는 연결 종료 명령어임
  printf("/exit : disconnect\n");
  printf("Send : ");

  // 대화내용을 입력받음. fflush(stdin)를 입력 버퍼를 비움
  fflush(stdin);
  scanf_s("%[^\n]", sendBuffer, MAXBUF);

  n = strlen(sendBuffer);

  // 입력하는동안 접속이 끊겻다면 소켓을 닫고, 리턴
  if(isDisconnected)
  {
   closesocket(c_socket);
   return 0;
  }

  // 그냥 엔터를 쳣거나 하면 무시
  if(n <= 0)
   continue;

  // 종료 명령어를 입력 했는지 체크
  if(strcmp(sendBuffer, "/exit") == 0)
  {
   closesocket(c_socket);
   isDisconnected = true;
   return 0;
  }

  // 상대편으로데 메시지를 전송
  send(c_socket, sendBuffer,n, 0);

  // 메시지를 대화내용에 저장하고 표시
  EnterCriticalSection(&hCriticalSection);
  memset(dialog[curLine], 0, sizeof(dialog[curLine]));
  strcpy(dialog[curLine], "Local : ");
  strcat(dialog[curLine], sendBuffer);
  show_dialog();

  curLine = (curLine + 1) % MAXLINE;
  LeaveCriticalSection(&hCriticalSection);


 };

 return 0;
}

추천 비추천

0

고정닉 0

0

댓글 영역

전체 댓글 0
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 뛰어난 운동 신경으로 남자와 싸워도 이길 것 같은 여자 스타는? 운영자 25/11/24 - -
이슈 [디시人터뷰] 충무로가 주목하는 신예, '세계의 주인' 서수빈 운영자 25/11/24 - -
AD 대학생 필수템! What's in my Bag 운영자 25/11/21 - -
300121 형들 좋아하는 문제냄 [4] asd(218.237) 12.01.26 77 0
300120 프로그래머 구하는 사람들을 보면 [1] Ynobe갤로그로 이동합니다. 12.01.26 128 1
300117 횽들 뭐좀 물어볼께요 AVR ? ATMEGA?? [16] 아잉(220.149) 12.01.26 213 0
300116 이걸 어쩌지 단순 연결리스트를 구현해 오라는데 [2] = _=갤로그로 이동합니다. 12.01.26 86 0
300115 WEB 프리랜서 vs SW 프리랜서 vs SI 프리랜서 [4] ㅇㅇ(221.147) 12.01.26 177 0
300112 애플스크립트 할줄 아는사람? ㅇㅇ(218.152) 12.01.26 36 0
300111 ㅋㅋ 횽들있자나 [3] ㅁㄴㅁㄴ(58.148) 12.01.26 86 0
300110 치킨먹고싶다...... dlbo갤로그로 이동합니다. 12.01.26 41 0
300109 횽들은 자신의 능력에 대한 자신감이 있어? [11] 어슐러르귄갤로그로 이동합니다. 12.01.26 187 0
300108 공지 돌아왔네.. HJH_갤로그로 이동합니다. 12.01.25 68 0
300107 안드로이드 ms사 api 이런거 있엉? [2] (221.133) 12.01.25 94 0
300106 형들 말 듣고 샀음 [5] ㅇㅁㅎ(110.47) 12.01.25 192 0
300104 학원출신 일용잡부.... [1] 후덜덜(58.140) 12.01.25 211 0
300102 5일 내내 컴퓨터 앞에 앉아 있으니 토할 거 같다 [2] ㅁㄴㄻㄹ갤로그로 이동합니다. 12.01.25 135 0
300101 진로상담... [4] 후덜덜(58.140) 12.01.25 112 0
300100 서울 도착... [1] 캐피곤닭(121.88) 12.01.25 68 0
300099 왜... 왜???? 왜자꾸 인터뷰 하자는글이 이케 많아??? 의문(116.125) 12.01.25 80 0
300097 아 자랑하고 싶다 자랑하고 싶다. 어떡해갤로그로 이동합니다. 12.01.25 127 0
300095 우분투의 패기, 셔틀워쓰의 패기 [2] 2(219.255) 12.01.25 88 0
일대일 채팅 누가 물어봤지? 로또로(218.39) 12.01.25 211 0
300090 mbc왜 저럼? [1] 이모군(175.114) 12.01.25 58 0
300089 나 C#시작함 형들아 [7] 꿀레(121.168) 12.01.25 141 0
300088 야 이번에 주말근무 연장근로로 포함시켜서 제한하는거 어케생각하냐 [1] -_-)(220.80) 12.01.25 89 0
300087 전화번호 엑셀로 010 0001 0001 부터 끝까지 알려주세요 [1] 초딩6(58.141) 12.01.25 143 0
300082 혹시 은닉 마르코프 모델 (HMM) 개념 쎄워줄 횽 없음? [3] 생각놀이갤로그로 이동합니다. 12.01.25 161 0
300081 C# 으로 디씨에 글싸는 프로그램 만들려는데, 형님들 도와주세여 [7] 아아앙(220.149) 12.01.25 137 0
300080 ssd 활용 [15] DevilCruiser갤로그로 이동합니다. 12.01.25 229 0
300079 여자친구 진급탈락했다 ㅜㅜ [2] 으아(112.223) 12.01.25 183 0
300078 야!!! 내가 명함 받았다!!! [6] 어떡해갤로그로 이동합니다. 12.01.25 222 0
300077 여긴 뭐하는 곳인가욤~ [7] 이문동쮸쮸바갤로그로 이동합니다. 12.01.25 133 0
300076 빅데이터, 데이터마이닝쪽 전망은 어떰? [3] 가르파이(125.128) 12.01.25 212 0
300075 나 찾는 사람 있음? [4] 외계달팽갤로그로 이동합니다. 12.01.25 112 0
300073 공고출신이라 그런지 기초지식이 없어 뒈지겠다 [1] 1(118.220) 12.01.25 118 0
300072 여자동물은 이상해 [4] 씨발라드세요갤로그로 이동합니다. 12.01.25 177 0
300071 적성검사.jpg [2] Gavi_cp갤로그로 이동합니다. 12.01.25 180 0
300070 엑셀 잘하는 형님들 ㅜㅠ 010-****-0001 [38] 제발 ㅠㅜ(211.109) 12.01.25 227 0
300069 형들 담달에 자바 교육원가서 배울건데 그전에 초급자 추천책좀 꽁치(118.42) 12.01.25 67 0
300067 winapi 책 추천좀 [7] 11(118.220) 12.01.25 113 0
300066 프갤은 찾아 들어오는게 아니야,, [1] ㅋㄱ(183.96) 12.01.25 85 0
300065 횽들 프로그래밍으로 문서만들기 질문 좀. ㅇㅇ(119.71) 12.01.25 41 0
300064 번호 이동 했는데 아직까지 내 폰 살아있네... [3] 좋은아버지갤로그로 이동합니다. 12.01.25 57 0
300063 형들 c언어 소켓프로그래밍 공부하고 싶은데요.. [10] vise(118.46) 12.01.25 260 0
300062 프로젝트가 없긴 없나봐 데브렉 보니 장난아니군 [2] 거칠게갤로그로 이동합니다. 12.01.25 1268 0
300061 윤성우 저자의 열혈강의 말이야....이거맞나? [3] 열혈강의(211.212) 12.01.25 177 0
300060 잉여력을 발휘해서 뭔가 만들어 내는게 더 재미있는거 같더라. [1] 거칠게갤로그로 이동합니다. 12.01.25 81 0
300059 클래스부터 좀 헷갈림 [1] 막준갤로그로 이동합니다. 12.01.25 79 0
300058 요즘은 기업들이 하청보다는 직접 개발을 하려는거 같어 [1] 거칠게갤로그로 이동합니다. 12.01.25 121 0
300057 HTML5 아주 얇은 걸로 공부는 끝냈는데 뭔가 좀 많이 부족함 ㅋㅋㅋ [1] 거칠게갤로그로 이동합니다. 12.01.25 133 0
300056 형들 질문점.. 센차터치야 [4] 갤로그로 이동합니다. 12.01.25 77 0
300055 프갤 찾아 들어오기 힘드네 [1] ㅇㅇㅇ갤로그로 이동합니다. 12.01.25 56 0
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

디시미디어

디시이슈

1/2