00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <windows.h>
00025 #include <winsock2.h>
00026
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <time.h>
00030
00031 #undef GLW_SERVER
00032
00033 #include "NetCommon.h"
00034 #include "port/Glw.h"
00035 #include "Memory.h"
00036 #include "debug.h"
00037 #include "Net.h"
00038 #include "Client.h"
00039
00040
00041
00042 #define SOCK_CLOSE_BUFSIZE 256
00043
00044 static char client_loopback[]="127.0.0.1";
00045 static char *client_address=client_loopback;
00046 static HWND global_window;
00047 static struct glw_Connection *global_conn;
00048 static int quit=0;
00049 static int async=0;
00050
00051
00052 struct glw_Connection
00053 {
00054 struct glw_ConnUser cuser;
00055 SOCKET sd;
00056 struct glw_SockMsg sockmsg;
00057 u32 completed;
00058 u8 *write_buffer;
00059 int byteorder;
00060 };
00061
00062 struct glw_Timer
00063 {
00064 u32 userdata;
00065
00066 u32 id;
00067 };
00068
00069
00070 static struct glw_Event curr_event;
00071
00072
00073
00074 u32 glw_htonl(u32 value)
00075 {
00076 return(htonl(value));
00077 }
00078
00079 u32 glw_ntohl(u32 value)
00080 {
00081 return(ntohl(value));
00082 }
00083
00084
00085 int glw_Recv(u32 connection, u8 *buff, int bufflen)
00086 {
00087 struct glw_Connection *conn=(struct glw_Connection *)connection;
00088 int ret=0;
00089
00090 debug_Begin();
00091
00092 if(conn!=NULL&&buff!=NULL&&bufflen>0)
00093 {
00094 ret=recv(conn->sd,buff,bufflen,0);
00095 }
00096
00097 debug_End();
00098
00099 return(ret);
00100 }
00101
00102
00103 int glw_Send(u32 connection, u8 *buff, int bufflen)
00104 {
00105 struct glw_Connection *conn=(struct glw_Connection *)connection;
00106 int ret=0;
00107
00108 debug_Begin();
00109
00110 if(conn!=NULL&&buff!=NULL&&bufflen>0)
00111 {
00112 ret=send(conn->sd,buff,bufflen,0);
00113 }
00114
00115 debug_End();
00116
00117 return(ret);
00118 }
00119
00120
00121 int glw_SendMsg(u32 connection, u8 type, u32 id, u8 *buff, int bufflen)
00122 {
00123 struct glw_Connection *conn=(struct glw_Connection *)connection;
00124 u8 header[GLW_HEADER_LENGTH];
00125 int mlen;
00126
00127 debug_Begin();
00128
00129 mlen=bufflen+GLW_HEADER_LENGTH;
00130
00131
00132 header[0]='?';
00133 header[1]=type;
00134 *((u32 *)&header[2])=htonl(mlen);
00135 *((u32 *)&header[6])=htonl(id);
00136 if(mlen<NET_WRITE_BUFFER_SIZE)
00137 {
00138 memcpy(conn->write_buffer,header,GLW_HEADER_LENGTH);
00139 if(bufflen>0) memcpy(conn->write_buffer+GLW_HEADER_LENGTH,buff,bufflen);
00140 send(conn->sd,conn->write_buffer,mlen,0);
00141 }
00142 else
00143 {
00144 send(conn->sd,header,GLW_HEADER_LENGTH,0);
00145 if(bufflen>0&&buff!=NULL) send(conn->sd,buff,bufflen,0);
00146 }
00147
00148 debug_End();
00149
00150 return(0);
00151 }
00152
00153
00154 static void glw_Client(char *address, int port)
00155 {
00156 struct in_addr Address;
00157 SOCKET sd;
00158 u_long RemoteAddress;
00159 struct hostent *pHE;
00160 struct sockaddr_in sinRemote;
00161 WSADATA wsaData;
00162 struct glw_Connection *conn;
00163 int NewBytes;
00164 char ReadBuffer[SOCK_CLOSE_BUFSIZE];
00165
00166 debug_Begin();
00167
00168 if(WSAStartup(MAKEWORD(1,1),&wsaData)==0)
00169 {
00170 printf("Establishing the client...\n");
00171 RemoteAddress=inet_addr(address);
00172 if(RemoteAddress==INADDR_NONE)
00173 {
00174 pHE=gethostbyname(address);
00175 if(pHE!=0)
00176 {
00177 RemoteAddress=*((u_long*)pHE->h_addr_list[0]);
00178 }
00179 }
00180 if(RemoteAddress!=INADDR_NONE)
00181 {
00182 memcpy(&Address,&RemoteAddress,sizeof(u_long));
00183 sd=socket(AF_INET, SOCK_STREAM, 0);
00184 if(sd!=INVALID_SOCKET)
00185 {
00186 sinRemote.sin_family=AF_INET;
00187 sinRemote.sin_addr.s_addr=RemoteAddress;
00188 sinRemote.sin_port=htons(port);
00189 if(connect(sd,(struct sockaddr *)&sinRemote,sizeof(struct sockaddr_in))==SOCKET_ERROR)
00190 {
00191 sd=INVALID_SOCKET;
00192 }
00193 }
00194 if(INVALID_SOCKET!=sd)
00195 {
00196 if(NULL!=(conn=mem_calloc(1,sizeof(struct glw_Connection))))
00197 {
00198 if(NULL!=(conn->write_buffer=mem_malloc(NET_WRITE_BUFFER_SIZE)))
00199 {
00200 conn->sd=sd;
00201 printf("connected to server\n");
00202 client_Init((u32)conn,&conn->byteorder);
00203 mem_free(conn->write_buffer);
00204 }
00205 mem_free(conn);
00206 }
00207 if(shutdown(sd,SD_SEND)!=SOCKET_ERROR)
00208 {
00209 while(1)
00210 {
00211 NewBytes=recv(sd,ReadBuffer,SOCK_CLOSE_BUFSIZE,0);
00212 if(NewBytes==0||NewBytes==SOCKET_ERROR) break;
00213 }
00214 closesocket(sd);
00215 }
00216 }
00217 }
00218 WSACleanup();
00219 }
00220
00221 debug_End();
00222 }
00223
00224
00225 static int glw_ReadMessage(struct glw_Connection *conn)
00226 {
00227 char header[GLW_HEADER_LENGTH];
00228 int rcv=0,r=0,ret=0;
00229 SYSTEMTIME stime;
00230
00231 if(conn->completed==0)
00232 {
00233
00234 while(rcv<GLW_HEADER_LENGTH)
00235 {
00236 if((r=recv(conn->sd,header+rcv,GLW_HEADER_LENGTH-rcv,0))<=0)
00237 {
00238 if(WSAGetLastError()==WSAEWOULDBLOCK)
00239 {
00240 fd_set fdread;
00241 FD_ZERO(&fdread);
00242 FD_SET(conn->sd,&fdread);
00243 if((r=select(0,&fdread,NULL,NULL,NULL))==SOCKET_ERROR) break;
00244 }
00245 else break;
00246 if((r=recv(conn->sd,header+rcv,GLW_HEADER_LENGTH-rcv,0))<=0) break;
00247 }
00248 rcv+=r;
00249 }
00250 if(r>=0&&header[0]=='?')
00251 {
00252 conn->sockmsg.type=(int)header[1];
00253 conn->sockmsg.length=ntohl(*((u32 *)&header[2]));
00254 conn->sockmsg.id=ntohl(*((u32 *)&header[6]));
00255 conn->sockmsg.body=mem_malloc(conn->sockmsg.length-GLW_HEADER_LENGTH);
00256 conn->completed=GLW_HEADER_LENGTH;
00257
00258 if(conn->sockmsg.body==NULL)
00259 {
00260
00261 conn->completed=0;
00262 }
00263 }
00264 else
00265 {
00266
00267 ret=-1;
00268 if(r>0)
00269 {
00270 int i,j,c;
00271 printf("***BAD MESSAGE:\n ");
00272 for(j=i=0;i<r;i++)
00273 {
00274 c=*(header+rcv-r+i);
00275 printf("%02x '%c' ",(unsigned short)c,(c>32||c<127?c:'.'));
00276 if((++j%8)==0) printf("\n ");
00277 }
00278 printf("\n");
00279 }
00280 else
00281 {
00282 printf("***BAD MESSAGE ret=%d errcode=%d\n",r,WSAGetLastError());
00283 }
00284 }
00285 }
00286 else
00287 {
00288
00289 r=recv( conn->sd,conn->sockmsg.body+conn->completed-GLW_HEADER_LENGTH,
00290 conn->sockmsg.length-conn->completed,0);
00291 if(r>0)
00292 {
00293 conn->completed+=r;
00294 if(conn->completed>=conn->sockmsg.length)
00295 {
00296 conn->completed=0;
00297 curr_event.event=GLWEV_SOCKET;
00298 curr_event.data=(u32)&conn->sockmsg;
00299 curr_event.second=(u32)time(NULL);
00300 GetSystemTime(&stime);
00301 curr_event.millis=stime.wMilliseconds;
00302 }
00303 }
00304 }
00305 return(ret);
00306 }
00307
00308
00309 int glw_MainLoopCli(u32 connection, u32 userdata)
00310 {
00311
00312 struct glw_Connection *conn=(struct glw_Connection *)connection;
00313 MSG Message;
00314
00315 debug_Begin();
00316
00317 debug_Message("ByteOrder: %d",conn->byteorder);
00318
00319
00320 global_conn=conn;
00321 do
00322 {
00323 if(async==0)
00324 {
00325 WSAAsyncSelect(conn->sd,global_window,WM_APP,FD_READ);
00326 async=1;
00327 }
00328 quit=0;
00329 curr_event.event=0L;
00330 curr_event.window=0L;
00331 curr_event.userdata=userdata;
00332 curr_event.mousex=curr_event.mousey=0;
00333
00334 GetMessage(&Message,NULL,0,0);
00335 TranslateMessage(&Message);
00336 DispatchMessage(&Message);
00337
00338
00339
00340 if(curr_event.event!=0L&&0!=client_CliProcessMessage(connection,curr_event.userdata,(struct glw_SockMsg *)curr_event.data)) break;
00341
00342 } while(quit==0);
00343 WSAAsyncSelect(conn->sd,global_window,0,0);
00344 async=0;
00345
00346
00347 debug_End();
00348
00349 return(0);
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 LRESULT CALLBACK glw_StdWindowProc(HWND Window, UINT MessageType, WPARAM FirstParameter, LPARAM SecondParameter)
00367 {
00368 LRESULT ret=1L;
00369
00370 debug_Begin();
00371
00372 switch(MessageType)
00373 {
00374 case WM_TIMER:
00375 {
00376 struct glw_Timer *timer=(struct glw_Timer *)FirstParameter;
00377
00378
00379
00380 if(timer!=NULL)
00381 {
00382
00383 client_TimerHandler((u32)timer,timer->userdata);
00384
00385 KillTimer(global_window,timer->id);
00386 ret=0;
00387 }
00388 break;
00389 }
00390 case WM_APP:
00391 {
00392
00393 if(0>glw_ReadMessage(global_conn)) printf("***BAD MESSAGE!!\n");
00394 ret=0;
00395 break;
00396 }
00397 }
00398
00399 debug_End();
00400
00401 return(ret);
00402 }
00403
00404
00405 int WINAPI WinMain(HINSTANCE Instance, HINSTANCE PreviousInstance, LPSTR CommandLine, int CommandShow)
00406 {
00407 WNDCLASSEX WindowClass;
00408
00409 debug_Begin();
00410
00411 if(strlen(CommandLine)>=7) client_address=CommandLine;
00412
00413 WindowClass.cbSize = sizeof(WNDCLASSEX);
00414 WindowClass.style = 0;
00415 WindowClass.lpfnWndProc = glw_StdWindowProc;
00416 WindowClass.cbClsExtra = 0;
00417 WindowClass.cbWndExtra = 0;
00418 WindowClass.hInstance = Instance;
00419 WindowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
00420 WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
00421 WindowClass.hbrBackground = GetStockObject(WHITE_BRUSH);
00422 WindowClass.lpszMenuName = NULL;
00423 WindowClass.lpszClassName = "glw_StdClientWC";
00424 WindowClass.hIconSm = NULL;
00425 if(RegisterClassEx(&WindowClass)!=0)
00426 {
00427 if((global_window=CreateWindowEx(
00428 WS_EX_OVERLAPPEDWINDOW,
00429 "glw_StdClientWC",
00430 NULL,
00431 WS_OVERLAPPED,
00432 1, 1, 3, 3,
00433 NULL,
00434 NULL,
00435 Instance,
00436 NULL))!=NULL)
00437 {
00438 ShowWindow(global_window,SW_HIDE);
00439
00440
00441 glw_Client(client_address,net_GetPort());
00442
00443
00444 DestroyWindow(global_window);
00445 }
00446 }
00447
00448 mem_trace_report();
00449
00450 debug_End();
00451
00452 return(0L);
00453 }
00454
00455
00456 u32 glw_TimerStart(u32 window, u32 millisec, u32 userdata)
00457 {
00458 struct glw_Timer *timer;
00459 u32 id;
00460
00461 debug_Begin();
00462
00463 if(NULL!=(timer=mem_malloc(sizeof(struct glw_Timer))))
00464 {
00465 timer->userdata=userdata;
00466
00467
00468 id=SetTimer(global_window,(u32)timer,(UINT)millisec,(TIMERPROC)NULL);
00469 timer->id=id;
00470 }
00471
00472 debug_End();
00473
00474 return((u32)timer);
00475 }
00476
00477
00478 void glw_TimerCancel(u32 window, u32 id)
00479 {
00480 struct glw_Timer *timer=(struct glw_Timer *)id;
00481
00482 debug_Begin();
00483
00484 if(timer!=NULL)
00485 {
00486 KillTimer(global_window,timer->id);
00487 mem_free(timer);
00488 }
00489
00490 debug_End();
00491 }
00492
00493
00494 void glw_CloseApp(u32 connection)
00495 {
00496 quit=1;
00497 }