Post
2018/10/04 - [Programing/Server] - IOCP window 채팅 클라이언트 소스
IOCP window 채팅 클라이언트 소스
아래는 IOCP window 채팅 클라이언트 프로젝트이다
#include#include #include #include #include #include #include #include #include "resource.h" #include #pragma comment(lib, "ws2_32.lib") struct SOCKDATA { SOCKET hSocket; SOCKADDR_IN servAdr; }; SOCKET hSocket = 0; // 소켓. 메시지 처리에서도 사용해야되서 전역변수로 선언 HWND hMsgWnd = 0; // 메시지 받고 나서 ui처리해야 되서 전역변수로 선언 #pragma region RegionName #define BUF_SIZE 1024 void ErrorHandling(const char* message); void StartServerConnect(WSADATA& wsaData, SOCKET& hSocket, SOCKADDR_IN& servAdr); // 소켓 초기화 DWORD WINAPI ServerThreadMain(LPVOID socket); // 서버와 데이터를 주고 받는 Thread BOOL Dlg_OnInitDialog(HWND hWnd, HWND hWndFocus, LPARAM lParam) { // WM_INITDIALOG: Dialog Box 초기화 코드 작성 return (TRUE); } void Dlg_OnCommand(HWND hWnd, int id, HWND hWndCtl, UINT codeNotify) { if (0 == hMsgWnd) { hMsgWnd = hWnd; } //WM_COMMAND switch (id) { case IDOK: { TCHAR buff[BUF_SIZE]; GetDlgItemText(hWnd, IDC_CHAT_ENTER, buff, BUF_SIZE); char temp[BUF_SIZE]; WideCharToMultiByte(CP_ACP, 0, buff, BUF_SIZE, temp, BUF_SIZE, NULL, NULL); printf("%s \n", temp); int len = strlen(temp); send(hSocket, temp, len, 0); memset(buff, 0, BUF_SIZE); // 글자 없애기 SetDlgItemText(hWnd, IDC_CHAT_ENTER, buff); break; } case WM_DESTROY: exit(0); break; } } // DialogBox Procedure INT_PTR WINAPI Dlg_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: return (SetDlgMsgResult(hWnd, uMsg, HANDLE_WM_INITDIALOG((hWnd), (wParam), (lParam), (Dlg_OnInitDialog)))); case WM_COMMAND: return (SetDlgMsgResult(hWnd, uMsg, HANDLE_WM_COMMAND((hWnd), (wParam), (lParam), (Dlg_OnCommand)))); } return (FALSE); } int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { WSADATA wsaData; SOCKADDR_IN servAdr; StartServerConnect(wsaData, hSocket, servAdr); UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // DialogBox생성 함수 DialogBox(hInstance, MAKEINTRESOURCE(CHAT_DIALOG/*DialogBox ID*/), NULL, Dlg_Proc/*DialogBox Procedure*/); return(0); } DWORD WINAPI ServerThreadMain(LPVOID data) { SOCKDATA* socketInfo = (SOCKDATA*)data; if (NULL == socketInfo) { return 0; } if (connect(socketInfo->hSocket, (SOCKADDR*)(&socketInfo->servAdr), sizeof(socketInfo->servAdr)) == SOCKET_ERROR) { DWORD dwError = GetLastError(); ErrorHandling("connect() error!"); } else puts("Connected..........."); char message[BUF_SIZE]; memset(message, 0, BUF_SIZE); TCHAR uniMessage[BUF_SIZE]; memset(uniMessage, 0, BUF_SIZE * sizeof(TCHAR)); int strLen = 0; int readLen = 0; while (true) { //fputs("Input message(Q to quit): ", stdout); //fgets(message, BUF_SIZE, stdin); //if (!strcmp(message, "q\n") || !strcmp(message, "Q\n")) // break; //strLen = strlen(message); //send(socketInfo->hSocket, message, strLen, 0); readLen = 0; while (1) { memset(message, 0, BUF_SIZE); readLen += recv(socketInfo->hSocket, &message[readLen], BUF_SIZE - 1, 0); if (readLen >= strLen) break; } strLen = readLen; message[strLen] = 0; // 유니코드로 변경 memset(uniMessage, 0, BUF_SIZE * sizeof(TCHAR)); // 유니코드 변경 전 유니코드 길이 구하기 int nUniLen = MultiByteToWideChar(CP_ACP, 0, message, strlen(message), NULL, NULL); MultiByteToWideChar(CP_ACP, 0, message, strLen+1, uniMessage, nUniLen); if (0 != hMsgWnd) { //SetDlgItemText(hMsgWnd, CHAT_VIEW, uniMessage); SendDlgItemMessage(hMsgWnd, CHAT_VIEW, LB_GETCURSEL, 0, 0); SendDlgItemMessage(hMsgWnd, CHAT_VIEW, LB_ADDSTRING, 0, (LPARAM)uniMessage); } strLen = 0; //printf("Message from server: %s", message); } delete socketInfo; closesocket(socketInfo->hSocket); WSACleanup(); return 0; } void StartServerConnect(WSADATA& wsaData, SOCKET& hSocket, SOCKADDR_IN& servAdr) { 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; inet_pton(AF_INET, "127.0.0.1", &(servAdr.sin_addr)); servAdr.sin_port = htons(atoi("7777")); SOCKDATA* sockData = new SOCKDATA(); sockData->hSocket = hSocket; sockData->servAdr = servAdr; // 서버와 통신할 thread 생성 _beginthreadex(NULL, 0, (_beginthreadex_proc_type)ServerThreadMain, (LPVOID)sockData, 0, NULL); } void ErrorHandling(const char *message) { fputs(message, stderr); fputc('\n', stderr); exit(1); } #pragma endregion
Dialog ID : CHAT_DIALOG
채팅 ListView ID : CHAT_VIEW (Sort 하지말것)
채팅 메시지 입력 Edit ID : IDC_CHAT_ENTER
확인 버튼 ID : IDOK
이전에 올린 IOCP 채팅 서버와 대응하는 클라이언트다
'이전게시판 > Server' 카테고리의 다른 글
IOCP 채팅 서버 소스 예제 (0) | 2018.10.04 |
---|---|
C4996 에러 (0) | 2018.09.28 |
LNK2019: __imp__closesocket@4 외부 기호(참조 위치: _main 함수)에서 확인하지 못했습니다. (0) | 2018.09.28 |
구글 프로토콜 버퍼 C++ Window 예제 (Google Protocol buffer) (0) | 2018.07.27 |
기본 서버 예제의 문제점 (0) | 2018.07.05 |
C4996 inet_addr Error Solution (0) | 2018.06.30 |
ip주소 추적 (0) | 2018.04.21 |
hosts파일, DNS (0) | 2018.04.21 |