"IOCP 채팅 클라이언트"에 해당되는 글 - 1건
Post
2018/10/04 - [Programing/Server] - IOCP window 채팅 클라이언트 소스
IOCP window 채팅 클라이언트 소스
아래는 IOCP window 채팅 클라이언트 프로젝트이다
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | #include <stdio.h> #include <stdlib.h> #include <winsock2.h> #include <ws2tcpip.h> #include <windows.h> #include <windowsx.h> #include <process.h> #include <tchar.h> #include "resource.h" #include <string.h> #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 </string.h></tchar.h></process.h></windowsx.h></windows.h></ws2tcpip.h></winsock2.h></stdlib.h></stdio.h> |
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 |