Juu elikkäs, onkos WinAPI:lla mitään omaa messageensa WinSocketille? Eli esim. jos serveriltä tulee dataa nii WinAPI sais viestin WM_GETDATA tjt? Tai jos yhdistetään niin sais esim viestin WM_CONNECT tjt?
Funktiolla WSAAsyncSelect voi asettaa socketin tuottamaan erilaisista tapahtumista haluamiaan viestejä.
Kokeilin nytten jotain, mutta nytten on ongelmas se, että kun käyttäjä yrittää yhdistää clientillä serveriin , niin clientti kaatuu.
Serveri.cpp
Mikä vikana?
#include <windows.h> #include <winsock2.h> #define WM_SOCKET (WM_USER + 5) LRESULT CALLBACK ViestienKasittelija( HWND hWnd,UINT viesti, WPARAM wParam, LPARAM lParam); HRESULT LuoIkkuna(HINSTANCE hInstance,INT nCmdShow); void virhe_ilmoitus(int virheid); SOCKET alusta_winsock(HWND hWnd); HINSTANCE hInstance; int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPInstance, \ LPSTR lpCmdLine,int nCmdShow){ LuoIkkuna(hInstance,nCmdShow); MSG viesti; while(viesti.message != WM_QUIT){ if( PeekMessage( &viesti,NULL, 0U,0U,PM_REMOVE) ){ TranslateMessage( &viesti ); DispatchMessage( &viesti ); }else{ } } UnregisterClass("IkkunaLuokanNimi",hInstance); return 0; } HRESULT LuoIkkuna(HINSTANCE hInstance,INT nCmdShow){ HWND hWnd; alusta_winsock(hWnd); WNDCLASS ikkuna; ikkuna.style = CS_HREDRAW |CS_VREDRAW; ikkuna.lpfnWndProc = ViestienKasittelija; ikkuna.cbClsExtra = 0; ikkuna.cbWndExtra = 0; ikkuna.hInstance = hInstance; ikkuna.hIcon = LoadIcon((HINSTANCE) NULL,IDI_APPLICATION); ikkuna.hCursor = LoadCursor((HINSTANCE) NULL,IDC_ARROW); ikkuna.hbrBackground = (HBRUSH) COLOR_WINDOW; ikkuna.lpszMenuName = NULL; ikkuna.lpszClassName = "IkkunaLuokanNimi"; if(!RegisterClass(&ikkuna)) return false; hWnd = CreateWindow("IkkunaLuokanNimi", "Trox Lite", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, (HWND) NULL, (HMENU) NULL, hInstance, (LPVOID) NULL); if(!hWnd) return false; ShowWindow( hWnd,nCmdShow); UpdateWindow(hWnd); return S_OK; } LRESULT CALLBACK ViestienKasittelija( HWND hWnd,UINT viesti, WPARAM wParam, LPARAM lParam){ static HWND hwndYhdista; static HFONT hFont; char tdata[250]; SOCKET Accept; WSAAsyncSelect(Accept,hWnd,WM_SOCKET, FD_READ |FD_WRITE | FD_CLOSE); switch(viesti){ case WM_CREATE: hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT); hwndYhdista = CreateWindowEx(NULL, "button","Aktivoi", WS_CHILD | WS_VISIBLE |BS_PUSHBUTTON,10,10,100,30, hWnd,(HMENU) 0,hInstance,NULL); break; case WM_SOCKET: if(WSAGETSELECTERROR(lParam)){ closesocket((SOCKET) wParam); break; } switch(WSAGETSELECTEVENT(lParam)) { case FD_ACCEPT: Accept = accept(wParam,NULL,NULL); break; case FD_READ: recv(Accept,tdata,sizeof(tdata),0); break; case FD_WRITE: break; case FD_CLOSE: closesocket( (SOCKET)wParam); break; } break; case WM_DESTROY: PostQuitMessage(0); return false; break; case WM_COMMAND: switch (HIWORD(wParam)) { case BN_CLICKED: if ( LOWORD(wParam) == 0){ virhe_ilmoitus(0); } break; } break; } return DefWindowProc( hWnd,viesti,wParam,lParam); } void virhe_ilmoitus(int virheid){ if(virheid == 0){ MessageBeep (0); } } SOCKET alusta_winsock(HWND hWnd){ WSADATA wsd; SOCKET listen_sock; SOCKADDR_IN InternetAddr; WSAStartup(MAKEWORD(2,2),&wsd); listen_sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); InternetAddr.sin_family = AF_INET; InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY); InternetAddr.sin_port = htons(5150); bind(listen_sock,(PSOCKADDR)&InternetAddr,sizeof(InternetAddr)); WSAAsyncSelect(listen_sock,hWnd,WM_SOCKET,FD_ACCEPT | FD_CLOSE); listen(listen_sock,5); return listen_sock; }
kayttaja-3842 kirjoitti:
Mikä vikana?
Vähän kaikki. Esimerkkipätkää ei monta sekuntia jaksa kattella, mutta asioitten alustusjärjestys ja paluuarvojen käsittely eivät kyllä herätä toiveita koodin toimivuudesta.
Serverin koodin perusteella clientin kaatumisesta ei voi esittää kuin mielipiteitä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.