블로그 이미지
ludwings

카테고리

분류 전체보기 (130)
WIN API (22)
워게임 (61)
만든것 (2)
메모 (37)
Total18,086
Today0
Yesterday3
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

winapi ] 채팅 & 파일전송

2013. 5. 21. 14:30
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

WINAPI ] 간단한 채팅2

WIN API / 2013. 5. 7. 09:37

클라이언트

1. 접속한다

2. 문자열을 전송한다

2. 문자열이 들어오면 출력해준다.

클라이언트 부분은 기본에서 조금만 수정했다.

먼저 ID와  접속할 serverIP를 입력 받았다. 그리고 내가 입력한 문자열앞에 아이디를 추가해서 보낼 Sendmessage 함수를 만들었따.

char szHostname[128] = {0, };
char szServerIP[128] = {0,};
char sendbuf[DEFAULT_BUFLEN] = {0, };

 

int SendMessage(char* message)
{
 ZeroMemory(sendbuf, sizeof(sendbuf));
 sprintf(sendbuf, "[ %s ] %s", szHostname, message);
 return send(ConnectSocket, sendbuf, DEFAULT_BUFLEN, 0);
}

 

서버로부터 메세지를 받는걸 쓰레드러 돌려ㄷㄹ돌려

unsigned __stdcall  ReceiveData(void * args)
{
 char recvbuf[DEFAULT_BUFLEN] = {0, };
 int recvbuflen = DEFAULT_BUFLEN;
 int iResult;
 // Receive until the peer closes the connection
 while(1)
 {
  iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
  if ( iResult > 0 )
   printf("%s\n", recvbuf);
  else if ( iResult == 0 )
   continue;
  else
   printf("recv failed with error: %d\n", WSAGetLastError());
 }
}

_beginthreadex(NULL, 0, ReceiveData,0 ,0, NULL);

내가 입력한 문자열을 계속 전송해줘야하니 문자열을 보내는 부분을 while 문으로 반복해주는ㄱㅔ끝

while(1)
{
 char message[500];
 if(gets(message))
 {
  if(!strcmp(message, "EXIT"))
   break;
  SendMessage(message);
 }
}

 

서버

1 접속하는 모든 client를 vector에 저장.

2 문자열이 입력되면 저장된 모든 client에 재전송

3 client 연결이 끊어지면 vector에서 삭제

 

클라이언트가 새로접속하는지 계쏙감시하는 부분이 필요하고.

새로운 클라이언트가 접속하면 소켓을 vector에 저장하고

그 클라이언트가 보내는 메세지를 보고있는 스레드를 생성한다.

클라이언트를 감시하다가 클라이언트가 메세지를 보내면 그메세지를 모든 클라이언트들에게 재전송해준다.

//모든 사용자에게 재전송.

BOOL SendToAll(const char *recvbuf, int iResult)
{
 std::vector<SOCKET>::iterator it = clients.begin();
 for(it ; it < clients.end() ; it++)
 {
  send(*it, recvbuf, iResult, 0);
 }
 return TRUE;
}

// 클라이언트 감시.

DWORD WINAPI ReceiveAndPost(LPVOID arg)
{
 // Receive until the peer shuts down the connection
 SOCKET client = (SOCKET)arg;
 while(1) {
  if(clients.size() > 0)
  {
   iResult = recv(client, recvbuf, recvbuflen, 0);
   if (iResult > 0) {
    printf("Bytes Recieve : %s\n", recvbuf);
    // Echo the buffer back to the sender
    iSendResult = SendToAll(recvbuf, iResult);
    if (iSendResult == SOCKET_ERROR) {
     printf("send failed: %d\n", WSAGetLastError());
     closesocket(client);
     DisconnectClient(client);

     //WSACleanup();
     return 1;
    }
    printf("Bytes sent: %s\n", recvbuf);
   } else if (iResult == 0)
    printf("Connection closing...\n");
   else {
    printf("client has left\n");
    closesocket(client);
    DisconnectClient(client);
    return 1;
   } // end of else
  }
 }
 return 1;
}

 

 

//클라이언트 접속끊는 부분
BOOL DisconnectClient(SOCKET client
{
 std::vector<SOCKET>::iterator it = clients.begin();
 for(it ; it < clients.end() ; it++)
 {
  if( *it == client)
  {
   clients.erase(clients.begin());        
   break;
  }
 }
 
 return TRUE;
}

 

// main에서 클라이언트가 접속하는지 계속 감시한다./

while(1)
{
 ClientSocket = accept(ListenSocket, NULL, NULL);
 if(ClientSocket == INVALID_SOCKET)
 {
  printf("accept failed with error :%d\n", WSAGetLastError());
  closesocket(ListenSocket);
  WSACleanup();

  return 1;
 }

 clients.push_back(ClientSocket);
 hThread=CreateThread(NULL,0,ReceiveAndPost, (LPVOID)ClientSocket, 0, &dwThreaId);
}

끝!

'WIN API' 카테고리의 다른 글

Dll Injector, Dll Ejector  (0) 2013.10.11
#pragma once  (0) 2013.09.04
WINAPI ] 간단한 채팅2  (0) 2013.05.07
간단한 쓰레드 만들기  (0) 2013.05.06
WINAPI ] 채팅 프로그램1  (0) 2013.05.06
WINAPI ] tlhelp32 프로세스 목록 얻기  (0) 2013.05.06
Posted by ludwings
TAG WINAPI, 채팅

댓글을 달아 주세요

최근에 달린 댓글

최근에 받은 트랙백

글 보관함