1
我正在使用WM_SOCKET。服務器和客戶端運行良好。但是,如果我關閉客戶端並重新打開它FD_READ不響應只FD_CLOSE和FD_ACCEPT工作正常。請人幫我...WM_SOCKET ... FD_READ沒有響應
服務器代碼:
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib,"ws2_32.lib")
#define IDC_EDIT_IN 101
#define IDC_EDIT_OUT 102
#define IDC_MAIN_BUTTON 103
#define WM_SOCKET 104
int nPort=5555;
HWND hEditIn=NULL;
HWND hEditOut=NULL;
SOCKET Socket=NULL;
char szHistory[10000];
sockaddr sockAddrClient;
LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd)
{
WNDCLASSEX wClass;
ZeroMemory(&wClass,sizeof(WNDCLASSEX));
wClass.cbClsExtra=NULL;
wClass.cbSize=sizeof(WNDCLASSEX);
wClass.cbWndExtra=NULL;
wClass.hbrBackground=(HBRUSH)COLOR_WINDOW;
wClass.hCursor=LoadCursor(NULL,IDC_ARROW);
wClass.hIcon=NULL;
wClass.hIconSm=NULL;
wClass.hInstance=hInst;
wClass.lpfnWndProc=(WNDPROC)WinProc;
wClass.lpszClassName="Window Class";
wClass.lpszMenuName=NULL;
wClass.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClassEx(&wClass))
{
int nResult=GetLastError();
MessageBox(NULL,
"Window class creation failed\r\nError code:",
"Window Class Failed",
MB_ICONERROR);
}
HWND hWnd=CreateWindowEx(NULL, "Window Class", "Winsock Async Server",
WS_OVERLAPPEDWINDOW, 200, 200, 640, 480, NULL, NULL, hInst,
NULL);
if(!hWnd)
{
int nResult=GetLastError();
MessageBox(NULL,
"Window creation failed\r\nError code:",
"Window Creation Failed",
MB_ICONERROR);
}
ShowWindow(hWnd,nShowCmd);
MSG msg;
ZeroMemory(&msg,sizeof(MSG));
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_MAIN_BUTTON:
{
char szBuffer[1024];
ZeroMemory(szBuffer,sizeof(szBuffer));
SendMessage(hEditOut,
WM_GETTEXT,
sizeof(szBuffer),
reinterpret_cast<LPARAM>(szBuffer));
send(Socket,szBuffer,strlen(szBuffer),0);
SendMessage(hEditOut,WM_SETTEXT,NULL,(LPARAM)"");
}
break;
}
break;
case WM_CREATE:
{
ZeroMemory(szHistory,sizeof(szHistory));
// Create incoming message box
hEditIn=CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_AUTOVSCROLL|ES_AUTOHSCROLL,
50, 120, 400, 200, hWnd, (HMENU)IDC_EDIT_IN,
GetModuleHandle(NULL),
NULL);
if(!hEditIn)
{
MessageBox(hWnd,
"Could not create incoming edit box.",
"Error",
MB_OK|MB_ICONERROR);
}
HGDIOBJ hfDefault=GetStockObject(DEFAULT_GUI_FONT);
SendMessage(hEditIn,
WM_SETFONT,
(WPARAM)hfDefault,
MAKELPARAM(FALSE,0));
SendMessage(hEditIn,
WM_SETTEXT,
NULL,
(LPARAM)"Waiting for client to connect...");
// Create outgoing message box
hEditOut=CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT",
"", WS_CHILD|WS_VISIBLE|ES_MULTILINE|
ES_AUTOVSCROLL|ES_AUTOHSCROLL,
50, 50, 400, 60, hWnd,
(HMENU)IDC_EDIT_IN,
GetModuleHandle(NULL),
NULL);
if(!hEditOut)
{
MessageBox(hWnd,
"Could not create outgoing edit box.",
"Error",
MB_OK|MB_ICONERROR);
}
SendMessage(hEditOut,
WM_SETFONT,
(WPARAM)hfDefault,
MAKELPARAM(FALSE,0));
SendMessage(hEditOut,
WM_SETTEXT,
NULL,
(LPARAM)"Type message here...");
// Create a push button
HWND hWndButton=CreateWindow( "BUTTON",
"Send",
WS_TABSTOP|WS_VISIBLE|
WS_CHILD|BS_DEFPUSHBUTTON,
50, 330, 75, 23,
hWnd, (HMENU)IDC_MAIN_BUTTON,
GetModuleHandle(NULL),
NULL);
SendMessage(hWndButton,
WM_SETFONT,
(WPARAM)hfDefault,
MAKELPARAM(FALSE,0));
WSADATA WsaDat;
int nResult=WSAStartup(MAKEWORD(2,2),&WsaDat);
if(nResult!=0)
{
MessageBox(hWnd,
"Winsock initialization failed",
"Critical Error",
MB_ICONERROR);
SendMessage(hWnd,WM_DESTROY,NULL,NULL);
break;
}
Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(Socket==INVALID_SOCKET)
{
MessageBox(hWnd,
"Socket creation failed",
"Critical Error",
MB_ICONERROR);
SendMessage(hWnd,WM_DESTROY,NULL,NULL);
break;
}
SOCKADDR_IN SockAddr;
SockAddr.sin_port=htons(nPort);
SockAddr.sin_family=AF_INET;
SockAddr.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(Socket,(LPSOCKADDR)&SockAddr,sizeof(SockAddr))==SOCKET_ERROR)
{
MessageBox(hWnd,"Unable to bind socket","Error",MB_OK);
SendMessage(hWnd,WM_DESTROY,NULL,NULL);
break;
}
nResult=WSAAsyncSelect(Socket,
hWnd,
WM_SOCKET,
(FD_CLOSE|FD_ACCEPT|FD_READ));
if(nResult)
{
MessageBox(hWnd,
"WSAAsyncSelect failed",
"Critical Error",
MB_ICONERROR);
SendMessage(hWnd,WM_DESTROY,NULL,NULL);
break;
}
if(listen(Socket,(1))==SOCKET_ERROR)
{
MessageBox(hWnd,
"Unable to listen!",
"Error",
MB_OK);
SendMessage(hWnd,WM_DESTROY,NULL,NULL);
break;
}
}
break;
case WM_DESTROY:
{
PostQuitMessage(0);
shutdown(Socket,SD_BOTH);
closesocket(Socket);
WSACleanup();
return 0;
}
break;
case WM_SOCKET:
{
switch(WSAGETSELECTEVENT(lParam))
{
case FD_READ:
{
char szIncoming[1024];
ZeroMemory(szIncoming,sizeof(szIncoming));
int inDataLength=recv(Socket,
(char*)szIncoming,
sizeof(szIncoming)/sizeof(szIncoming[0]),
0);
strncat(szHistory,szIncoming,inDataLength);
strcat(szHistory,"\r\n");
SendMessage(hEditIn,
WM_SETTEXT,
sizeof(szIncoming)-1,
reinterpret_cast<LPARAM>(&szHistory));
}
break;
case FD_CLOSE:
{
MessageBox(hWnd,
"Client closed connection",
"Connection closed!",
MB_ICONINFORMATION|MB_OK); }
break;
case FD_ACCEPT:
{
int size=sizeof(sockaddr);
Socket=accept(wParam,&sockAddrClient,&size);
if (Socket==INVALID_SOCKET)
{
int nret = WSAGetLastError();
WSACleanup();
}
SendMessage(hEditIn,
WM_SETTEXT,
NULL,
(LPARAM)"Client connected!");
}
break;
}
}
}
return DefWindowProc(hWnd,msg,wParam,lParam);
}
客戶端代碼:
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib,"ws2_32.lib")
#define IDC_EDIT_IN 101
#define IDC_EDIT_OUT 102
#define IDC_MAIN_BUTTON 103
#define WM_SOCKET 104
char *szServer="localhost";
int nPort=5555;
HWND hEditIn=NULL;
HWND hEditOut=NULL;
SOCKET Socket=NULL;
char szHistory[10000];
LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd)
{
WNDCLASSEX wClass;
ZeroMemory(&wClass,sizeof(WNDCLASSEX));
wClass.cbClsExtra=NULL;
wClass.cbSize=sizeof(WNDCLASSEX);
wClass.cbWndExtra=NULL;
wClass.hbrBackground=(HBRUSH)COLOR_WINDOW;
wClass.hCursor=LoadCursor(NULL,IDC_ARROW);
wClass.hIcon=NULL;
wClass.hIconSm=NULL;
wClass.hInstance=hInst;
wClass.lpfnWndProc=(WNDPROC)WinProc;
wClass.lpszClassName="Window Class";
wClass.lpszMenuName=NULL;
wClass.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClassEx(&wClass))
{
int nResult=GetLastError();
MessageBox(NULL,
"Window class creation failed\r\nError code:",
"Window Class Failed",
MB_ICONERROR);
}
HWND hWnd=CreateWindowEx(NULL,
"Window Class",
"Windows Async Client",
WS_OVERLAPPEDWINDOW,
200,
200,
640,
480,
NULL,
NULL,
hInst,
NULL);
if(!hWnd)
{
int nResult=GetLastError();
MessageBox(NULL,
"Window creation failed\r\nError code:",
"Window Creation Failed",
MB_ICONERROR);
}
ShowWindow(hWnd,nShowCmd);
MSG msg;
ZeroMemory(&msg,sizeof(MSG));
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
{
ZeroMemory(szHistory,sizeof(szHistory));
// Create incoming message box
hEditIn=CreateWindowEx(WS_EX_CLIENTEDGE,
"EDIT",
"",
WS_CHILD|WS_VISIBLE|ES_MULTILINE|
ES_AUTOVSCROLL|ES_AUTOHSCROLL,
50,
120,
400,
200,
hWnd,
(HMENU)IDC_EDIT_IN,
GetModuleHandle(NULL),
NULL);
if(!hEditIn)
{
MessageBox(hWnd,
"Could not create incoming edit box.",
"Error",
MB_OK|MB_ICONERROR);
}
HGDIOBJ hfDefault=GetStockObject(DEFAULT_GUI_FONT);
SendMessage(hEditIn,
WM_SETFONT,
(WPARAM)hfDefault,
MAKELPARAM(FALSE,0));
SendMessage(hEditIn,
WM_SETTEXT,
NULL,
(LPARAM)"Attempting to connect to server...");
// Create outgoing message box
hEditOut=CreateWindowEx(WS_EX_CLIENTEDGE,
"EDIT",
"",
WS_CHILD|WS_VISIBLE|ES_MULTILINE|
ES_AUTOVSCROLL|ES_AUTOHSCROLL,
50,
50,
400,
60,
hWnd,
(HMENU)IDC_EDIT_IN,
GetModuleHandle(NULL),
NULL);
if(!hEditOut)
{
MessageBox(hWnd,
"Could not create outgoing edit box.",
"Error",
MB_OK|MB_ICONERROR);
}
SendMessage(hEditOut,
WM_SETFONT,(WPARAM)hfDefault,
MAKELPARAM(FALSE,0));
SendMessage(hEditOut,
WM_SETTEXT,
NULL,
(LPARAM)"Type message here...");
// Create a push button
HWND hWndButton=CreateWindow(
"BUTTON",
"Send",
WS_TABSTOP|WS_VISIBLE|
WS_CHILD|BS_DEFPUSHBUTTON,
50,
330,
75,
23,
hWnd,
(HMENU)IDC_MAIN_BUTTON,
GetModuleHandle(NULL),
NULL);
SendMessage(hWndButton,
WM_SETFONT,
(WPARAM)hfDefault,
MAKELPARAM(FALSE,0));
// Set up Winsock
WSADATA WsaDat;
int nResult=WSAStartup(MAKEWORD(2,2),&WsaDat);
if(nResult!=0)
{
MessageBox(hWnd,
"Winsock initialization failed",
"Critical Error",
MB_ICONERROR);
SendMessage(hWnd,WM_DESTROY,NULL,NULL);
break;
}
Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(Socket==INVALID_SOCKET)
{
MessageBox(hWnd,
"Socket creation failed",
"Critical Error",
MB_ICONERROR);
SendMessage(hWnd,WM_DESTROY,NULL,NULL);
break;
}
nResult=WSAAsyncSelect(Socket,hWnd,WM_SOCKET,(FD_CLOSE|FD_READ));
if(nResult)
{
MessageBox(hWnd,
"WSAAsyncSelect failed",
"Critical Error",
MB_ICONERROR);
SendMessage(hWnd,WM_DESTROY,NULL,NULL);
break;
}
// Resolve IP address for hostname
struct hostent *host;
if((host=gethostbyname(szServer))==NULL)
{
MessageBox(hWnd,
"Unable to resolve host name",
"Critical Error",
MB_ICONERROR);
SendMessage(hWnd,WM_DESTROY,NULL,NULL);
break;
}
// Set up our socket address structure
SOCKADDR_IN SockAddr;
SockAddr.sin_port=htons(nPort);
SockAddr.sin_family=AF_INET;
SockAddr.sin_addr.s_addr=*((unsigned long*)host->h_addr);
connect(Socket,(LPSOCKADDR)(&SockAddr),sizeof(SockAddr));
}
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_MAIN_BUTTON:
{
char szBuffer[1024];
int test=sizeof(szBuffer);
ZeroMemory(szBuffer,sizeof(szBuffer));
SendMessage(hEditOut,
WM_GETTEXT,
sizeof(szBuffer),
reinterpret_cast<LPARAM>(szBuffer));
send(Socket,szBuffer,strlen(szBuffer),0);
SendMessage(hEditOut,WM_SETTEXT,NULL,(LPARAM)"");
}
break;
}
break;
case WM_DESTROY:
{
PostQuitMessage(0);
shutdown(Socket,SD_BOTH);
closesocket(Socket);
WSACleanup();
return 0;
}
break;
case WM_SOCKET:
{
if(WSAGETSELECTERROR(lParam))
{
MessageBox(hWnd,
"Connection to server failed",
"Error",
MB_OK|MB_ICONERROR);
SendMessage(hWnd,WM_DESTROY,NULL,NULL);
break;
}
switch(WSAGETSELECTEVENT(lParam))
{
case FD_READ:
{
char szIncoming[1024];
ZeroMemory(szIncoming,sizeof(szIncoming));
int inDataLength=recv(Socket,
(char*)szIncoming,
sizeof(szIncoming)/sizeof(szIncoming[0]),
0);
strncat(szHistory,szIncoming,inDataLength);
strcat(szHistory,"\r\n");
SendMessage(hEditIn,
WM_SETTEXT,
sizeof(szIncoming)-1,
reinterpret_cast<LPARAM>(&szHistory));
}
break;
case FD_CLOSE:
{
MessageBox(hWnd,
"Server closed connection",
"Connection closed!",
MB_ICONINFORMATION|MB_OK);
closesocket(Socket);
SendMessage(hWnd,WM_DESTROY,NULL,NULL);
}
break;
}
}
}
return DefWindowProc(hWnd,msg,wParam,lParam);
}
如果沒有精神技能,這是無法回答的。請添加一些代碼,以便我們看到你在做什麼。 –
當套接字關閉時,爲什麼您要在服務器中發送'WM_DESTROY'?這可能會導致服務器應用程序退出,意味着客戶端_cant_再次連接,因爲沒有服務器偵聽。或者如果服務器沒有退出,它可能會停止正常工作。 –
抱歉,錯誤的代碼在關閉期間不會有任何WM_DESTROY。但結果是一樣的... FD_READ突然停止響應。 –