l聊天室
由于时间紧迫,我决定学习opengl的同时学习winsock,看了两个星期的windows socket编程,发现动手比看书效果好啊,于是,我决定写一个QQ聊天室的小程序,仿照书上的服务器端和客户端代码程序,今晚抽了一点时间把界面搞定了一部分(客户端),明天继续....编程的生活虽然枯燥,但是我会一直坚持下去滴....(代码写完就会上传)
路过的大侠,你们好,最近我写这个聊天室程序遇到瓶颈,发现在本地环回地址上能实现客户端和服务器端的正常通信,但是却无法再其他PC上实现连接,调试了半天发现当用户提交用户名和密码时send函数失败返回,可就是无法解决啊,希望各位路过的大侠能帮忙解决一下,在下感激不尽!!!
服务端主要程序:
// QQ_Server.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "QQ_Server.h"
#include "Resource.h"
#include<WinSock.h>
/////////数据库相关////////////////////
#include "sql.h"
#include "sqlext.h"
#include "sqltypes.h"
//////////////////////////////////////////////
//QQ_服务器端程序
//作者:郑金玮
//时间:2013.5.9
// 启用视觉样式
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publickeytoken='6595b64144ccf1df' language='*'\"")
////////对话框声明/////////
INT_PTR CALLBACK ServerDiaLogProc(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam);
//////////////////////////////////////////////
#define SERVER_message WM_USER+200
const int MaxNumber=5;
//必要的sock结构
int WSA_return;//返回的套接字信息
WSADATA WSAData;
SOCKET server_hSocket;//服务套接字
SOCKET Listen_hSocket;//监听套接字
struct sockaddr_in server_addr;//服务地址结构
struct sockaddr_in Listen_addr;//监听结构
int Listen_addrlen=sizeof(Listen_addr);
int fromlen=sizeof(server_addr);
BOOL server_bErr;//错误
UINT server_uPort;//端口
char ShowText[1024];//显示信息
char InputText[256];//管理员发送信息
char Receive_UserMsg_Text[256];//接受用户的发送过来的信息
char Receive_UserName_Text[256];//接收用户登录名
char Receive_UserPassword_Text[256];//接收用户的登录密码
SOCKET nSocket[MaxNumber];
char *ClientIP[MaxNumber];//接收用户的IP地址
int i;
//必要的信息提示
char ComeMsg[30]="正在尝试连接...\r\n";
char LeaveMsg[30]="离开聊天室\r\n";
char LeaveMsg1[30]="异常离开\r\n";
////////////////
//////////////////////////////////////////////
#define LOGIN_TIMEOUT 30
#define MAXBUFLEN 255
#define CHECKDBSTMTERROR(hwnd,result,hstmt) if(SQL_ERROR==result){ShowDBStmtError(hwnd,hstmt);return;}
static void ShowDBError(HWND hwnd,SQLSMALLINT type,SQLhandle sqlHandle)
{
char pStatus[10], pMsg[101];
SQLSMALLINT SQLmsglen;
char error[200] = {0};
SQLinteger SQLerr;
long erg2 = SQLGetDiagRec(type, sqlHandle,1,(SQLCHAR *)pStatus,&SQLerr,(SQLCHAR*)pMsg,100,&SQLmsglen);
wsprintf(error,"%s (%d)\n",pMsg,(int)SQLerr);
MessageBox(hwnd,error,"数据库执行错误",MB_ICONERROR|MB_OK);
}
static void ShowDBConnError(HWND hwnd,SQLHDBC hdbc)
{
ShowDBError(hwnd,SQL_HANDLE_DBC,hdbc);
}
static void ShowDBStmtError(HWND hwnd,SQLHSTMT hstmt)
{
ShowDBError(hwnd,SQL_HANDLE_STMT,hstmt);
}
///////////////////////////////
void Login(HWND hwnd,SOCKET nSock,char UserName[],char PassWord[],BOOL &check);//登录系统
//////////////////////////////////////
int WINAPI WinMain( __in Hinstance hInstance, __in_opt HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd )
{
DialogBox(hInstance,MAKEINTRESOURCE(IDD_ABOUTBOX),NULL,ServerDiaLogProc);
return 0;
}
////////对话框定义/////////
BOOL gb_Check[5]={FALSE,FALSE,FALSE,FALSE,FALSE};
void RegUserInfo(HWND hDlg,const char UserNamep[],const char PassWord[]);//用户注册
BOOL CALLBACK ServerDiaLogProc(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case SERVER_MESSAGE:
{
switch(lParam)
{
case FD_ACCEPT:
{
Listen_hSocket=accept(server_hSocket,(LPSOCKADDR)&Listen_addr,&Listen_addrlen);
if (Listen_hSocket==0)
{
MessageBox(hDlg,"Listen_hSocket接受失败",NULL,NULL);
}
for(int i=0;i<MaxNumber;i++)
{
if(nSocket[i]==0)
{
nSocket[i]=Listen_hSocket;
if(WSAAsyncSelect(nSocket[i],hDlg,SERVER_MESSAGE,FD_ACCEPT|FD_READ|FD_WRITE|FD_CLOSE)>0)
{
MessageBox(NULL,"异步模式创建失败!","警告!",MB_OK);
}
ClientIP[i]=inet_ntoa(Listen_addr.sin_addr);
break;
}
}
if(i<MaxNumber)
{
strcat(ShowText,ClientIP[i]);
strcat(ShowText,ComeMsg);
SetDlgItemText(hDlg,IDC_EDIT4,ShowText);
}
return TRUE;
}
case FD_READ:
{
for(int i=0;i<MaxNumber;i++)
{
if(nSocket[i]==wParam)
{
//将获取的用户名和密码访问数据库进行匹配Receive_UserMsg_Text
if (gb_Check[i]==FALSE)
{
int rec1;
int rec2;
char rec1s[30];
char rec2s[30];
rec1=recv(nSocket[i],Receive_UserName_Text,256,0);
rec2=recv(nSocket[i],Receive_UserPassWord_Text,256,0);
wsprintf(rec1s,"recv 字节:%d",rec1);
wsprintf(rec1s,"recv 字节:%d",rec2);
MessageBox(NULL,rec1s,NULL,NULL);
MessageBox(NULL,rec1s,NULL,NULL);
Login(hDlg,nSocket[i],Receive_UserName_Text,Receive_UserPassWord_Text,gb_Check[i]);//登录系统
}
if (gb_Check[i]==TRUE)
{
recv(nSocket[i],Receive_UserMsg_Text,256,0);
strcat(ShowText,ClientIP[i]);
strcat(ShowText,":");
strcat(ShowText,Receive_UserMsg_Text);
strcat(ShowText," \r\n");
SetDlgItemText(hDlg,IDC_EDIT4,ShowText);
}
}
}
return TRUE;
}
case FD_WRITE:
{
return TRUE;
}
case FD_CLOSE:
{
for(int i=0;i<MaxNumber;i++)
{
if(nSocket[i]==wParam)
{
strcat(ShowText,ClientIP[i]);
strcat(ShowText,LeaveMsg);
SetDlgItemText(hDlg,IDC_EDIT4,ShowText);
nSocket[i]=0;
gb_Check[i]=FALSE;
closesocket(nSocket[i]);
for(i=0;i<MaxNumber;i++)
{
if(nSocket[i]!=0)
{
send(nSocket[i],ClientIP[i],strlen(ClientIP[i]),0);
send(nSocket[i],LeaveMsg,strlen(LeaveMsg),0);
}
}
}
}
return TRUE;
}
default:
{
for(int i=0;i<MaxNumber;i++)
{
if(nSocket[i]==wParam)
{
strcat(ShowText,ClientIP[i]);
strcat(ShowText,LeaveMsg1);
SetDlgItemText(hDlg,IDC_EDIT4,ShowText);
nSocket[i]=0;
gb_Check[i]=FALSE;
closesocket(nSocket[i]);
for(i=0;i<MaxNumber;i++)
{
if(nSocket[i]!=0)
{
send(nSocket[i],ClientIP[i],strlen(ClientIP[i]),0);
send(nSocket[i],LeaveMsg1,strlen(LeaveMsg1),0);
}
}
}
}
return TRUE;
break;
}
}
}
case WM_LBUTTONDOWN: //当鼠标左键点击时可以拖曳窗口
{
SetFocus(hDlg);
postmessage(hDlg, WM_SYScommaND, SC_MOVE | HTCAPTION, 0);
return 0;
break;
}
case WM_INITDIALOG:
{
//初始化winsock环境
WSA_return=wsastartup(0x0002,&WSAData);
if(WSA_return!=0)
{
MessageBox(NULL,"初始化失败!","警告!",MB_OK);
WSACleanup();
}
// 设置字体参数
LOGFONT LogFont;
::memset(&LogFont, 0, sizeof(LOGFONT));
strcpy(LogFont.lfFaceName,"新宋体");
LogFont.lfWeight = 400;
LogFont.lfHeight = 18; // 字体大小
LogFont.lfCharSet = 134;
LogFont.lfOutPrecision = 3;
LogFont.lfClipPrecision = 2;
LogFont.lfOrientation = 45;
LogFont.lfQuality = 1;
LogFont.lfPitchAndFamily = 2;
// 创建字体
HFONT hFont = CreateFontindirect(&LogFont);
// 设置控件字体
HWND hEdit1=getdlgitem(hDlg,IDC_EDIT1);
HWND hEdit2=GetDlgItem(hDlg,IDC_EDIT2);
HWND hEdit3=GetDlgItem(hDlg,IDC_EDIT3);
HWND hEdit4=GetDlgItem(hDlg,IDC_EDIT4);
HWND hedit5=GetDlgItem(hDlg,IDC_EDIT5);
::SendMessage(hEdit1, WM_SETFONT, (WPARAM)hFont, 0);
::SendMessage(hEdit2, WM_SETFONT, (WPARAM)hFont, 0);
::SendMessage(hEdit3, WM_SETFONT, (WPARAM)hFont, 0);
::SendMessage(hEdit4, WM_SETFONT, (WPARAM)hFont, 0);
::SendMessage(hEdit5, WM_SETFONT, (WPARAM)hFont, 0);
SetDlgItemText(hDlg,IDC_EDIT1,"6060");
EnableWindow(GetDlgItem(hDlg,IDC_EDIT1),FALSE);
return (INT_PTR)TRUE;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDCANCEL:
case IDC_BUTTON4:
case IDOK:
{
//WSAAsyncSelect(server_hSocket,hDlg,0,0);
/*closesocket(server_hSocket);
WSACleanup();*/
PostQuitMessage(0);
EndDialog(hDlg,NULL);
break;
}
case IDC_BUTTON1://建立服务器
{
if(server_hSocket!=0)
{
closesocket(server_hSocket);
server_hSocket=0;
}
if(server_hSocket==0)
{
if((server_hSocket=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR)
{
MessageBox(NULL,"建立套接字失败!","警告!",MB_OK);
break;
}
if(WSAAsyncSelect(server_hSocket,hDlg,SERVER_MESSAGE,
FD_ACCEPT|FD_READ|FD_WRITE|FD_CLOSE)>0)
{
MessageBox(NULL,"异步模式创建失败!","警告!",MB_OK);
break;
}
}
server_addr.sin_family=AF_INET;
server_addr.sin_addr.S_un.S_addr=INADDR_ANY;
server_uPort=GetDlgItemInt(hDlg,IDC_EDIT1,&server_bErr,TRUE);
server_addr.sin_port=htons((u_short)server_uPort);
if(bind(server_hSocket,(LPSOCKADDR)&server_addr,sizeof(server_addr))==SOCKET_ERROR)
{
MessageBox(NULL,"绑定端口失败!","警告",MB_OK);
break;
}
if(listen(server_hSocket,5)==SOCKET_ERROR)
{
MessageBox(NULL,"侦听失败!","警告!",MB_OK);
break;
}
strcpy(ShowText,"服务器建立成功!\r\n");
SetDlgItemText(hDlg,IDC_EDIT4,ShowText);
return TRUE;
}
case IDC_BUTTON2://提交用户注册
{
char l_szUserName[256];
char l_szPassWord[256];
GetDlgItemText(hDlg,IDC_EDIT2,l_szUserName,strlen(l_szUserName));
GetDlgItemText(hDlg,IDC_EDIT3,l_szPassWord,strlen(l_szPassWord));
RegUserInfo(hDlg,l_szUserName,l_szPassWord);//用户注册
return TRUE;
}
case IDC_BUTTON3://发送信息
{
GetDlgItemText(hDlg,IDC_EDIT5,InputText,256);
//if(InputText[strlen(InputText)-1]=='\n')
strcat(ShowText,"管理员:\r\n ");
strcat(ShowText,InputText);
SetDlgItemText(hDlg,IDC_EDIT4,ShowText);
strcat(ShowText,"\r\n ");
for(i=0;i<MaxNumber;i++)
if(nSocket[i]!=0)
{
send(nSocket[i],"管理员:\r\n",strlen("管理员:\r\n"),0);
send(nSocket[i],InputText,strlen(InputText),0);
}
strcpy(InputText,"");
SetDlgItemText(hDlg,IDC_EDIT5,InputText);
break;
}
}
break;
}
}
return FALSE;
}
void Login(HWND hwnd,SOCKET nSock,char UserName[],char PassWord[],BOOL &check)//登录系统
{
//UserName
//PassWord
//先要排除一些异常
if (strcmp(UserName,"")==0 || strcmp(PassWord,"")==0)
{
char msgbuff[256];
strcpy(msgbuff,"mustfillnameandpassword");
send(nSock,msgbuff,strlen(msgbuff),0);
return;
}
SQLHENV henv = NULL;
SQLHDBC hdbc = NULL;
SQLHSTMT hstmt = NULL;
SQLRETURN result;
SQLCHAR ConnStrIn[MAX_PATH] = "DRIVER={mysql ODBC 5.1 Driver};SERVER={127.0.0.1};UID=root;PWD=root;DATABASE=qq_tiance;CharSet=GBK;";
SQLCHAR ConnStrOut[MAX_PATH];
//分配环境句柄
result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE,
&henv);
//设置管理环境属性
result = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3, 0);
//分配连接句柄
result = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
//设置连接属性
result = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT,
(void*)LOGIN_TIMEOUT, 0);
//连接数据库
result = SQLDriverConnect(hdbc,NULL,ConnStrIn,SQL_NTS,ConnStrOut,MAX_PATH,(SQLSMALLINT*)0,SQL_DRIVER_NOPROMPT);
if(SQL_ERROR==result)
{
ShowDBConnError(hwnd,hdbc);
return;
}
//初始化语句句柄
result = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
//SQL_NTS telling the function the previous parameter is NullTerminated String,
//please alculate the string length for me
CHAR sql[256];
lstrcpy(sql,"select FUserName,FPassWord from userlog");
result = SQLPrepare(hstmt,(SQLCHAR*)sql,SQL_NTS);
CHECKDBSTMTERROR(hwnd,result,hstmt);
result =SQLExecute(hstmt);
CHECKDBSTMTERROR(hwnd,result,hstmt);
SQLINTEGER cbsatid=SQL_NTS;
int found=1;
while (SQLFetch(hstmt)!=SQL_NO_DATA_FOUND)
{
char username[20];
SQLGetData(hstmt,1,SQL_C_CHAR,username,20,&cbsatid);
char password[20];
SQLGetData(hstmt,2,SQL_C_CHAR,password,20,&cbsatid);
if (strcmp(PassWord,password)==0)
{
if (strcmp(UserName,username)==0)
{
char msgbuff2[256];
strcpy(msgbuff2,"success");
send(nSock,msgbuff2,strlen(msgbuff2),0);
strcat(ShowText,UserName);
strcat(ShowText,"连接成功!\r\n");
SetDlgItemText(hwnd,IDC_EDIT4,ShowText);
found=0;
check=TRUE;
break;
}
}
}
if (1==found)
{
char msgbuff1[256];
strcpy(msgbuff1,"failedlogin");
send(nSock,msgbuff1,strlen(msgbuff1),0);
}
SQLFreeStmt(hstmt,SQL_CLOSE);
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC,hdbc);
SQLFreeHandle(SQL_HANDLE_ENV,henv);
}
void RegUserInfo(HWND hwnd,const char UserName[],const char PassWord[])//用户注册
{
if (*UserName==NULL || *PassWord==NULL)
{
MessageBox(hwnd,"请填写具体的用户名和密码!","错误",MB_OK|MB_ICONERROR);
return;
}
SQLHENV henv = NULL;
SQLHDBC hdbc = NULL;
SQLHSTMT hstmt = NULL;
SQLRETURN result;
SQLCHAR ConnStrIn[MAX_PATH] = "DRIVER={MySQL ODBC 5.1 Driver};SERVER={127.0.0.1};UID=root;PWD=root;DATABASE=qq_tiance;CharSet=GBK;";
SQLCHAR ConnStrOut[MAX_PATH];
//分配环境句柄
result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE,
&henv);
//设置管理环境属性
result = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3, 0);
//分配连接句柄
result = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
//设置连接属性
result = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT,
(void*)LOGIN_TIMEOUT, 0);
//连接数据库
result = SQLDriverConnect(hdbc,NULL,ConnStrIn,SQL_NTS,ConnStrOut,MAX_PATH,(SQLSMALLINT*)0,SQL_DRIVER_NOPROMPT);
if(SQL_ERROR==result)
{
ShowDBConnError(hwnd,hdbc);
return;
}
//初始化语句句柄
result = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
//SQL_NTS telling the function the previous parameter is NullTerminated String,
//please alculate the string length for me
CHAR sql[256];
wsprintf(sql,"insert into userlog(FUserName,FPassWord) values('%s','%s')",UserName,PassWord);
result = SQLPrepare(hstmt,(SQLCHAR*)sql,SQL_NTS);
CHECKDBSTMTERROR(hwnd,result,hstmt);
result =SQLExecute(hstmt);
CHECKDBSTMTERROR(hwnd,result,hstmt);
MessageBox(hwnd,"注册成功","",MB_ICONINFORMATION|MB_OK);
SQLFreeStmt(hstmt,SQL_CLOSE);
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC,hdbc);
SQLFreeHandle(SQL_HANDLE_ENV,henv);
}
客户端主要程序:
#include "stdafx.h"
#include "sock_client_wnd.h"
#include "Resource.h"
#include "OwnDrawButton.h"
#include<winsock.h>
/*
说明:server_wnd定义
*/
//构造函数
//GID+载入保护管理
Gdiplus::GdiplusStartupInput m_gdiplusStartupInput;
ULONG_PTR m_pGdiToken;
CClient::CClient(HINSTANCE hInst)
{
m_hInst=hInst;
strcpy(m_szClientWndClassName,"myserverclass");
strcpy(m_szClientWndName,"QQ聊天室_天策版");
m_x=200;
m_y=200;
m_Width=500;
m_Height=320;
m_WndStyle=WS_POPUP|WS_Border;
Gdiplus::GdiplusStartup(&m_pGdiToken,&m_gdiplusStartupInput,NULL);
}
//析构函数
CClient::~CClient()
{
m_hwnd=NULL;
Gdiplus::GdiplusShutdown(m_pGdiToken);
}
//初始化
void CClient::Init(void)
{
myclass.cbClsExtra=0;
myclass.cbWndExtra=0;
myclass.hbrBackground=(HBRUSH) GetStockObject (WHITE_BRUSH) ;
myclass.hCursor=LoadCursor(NULL,IDC_ARROW);
myclass.hIcon=LoadCursor(NULL,IDI_WINLOGO);
myclass.hInstance=m_hInst;
myclass.lpfnWndProc=ClientWndProc;
myclass.lpszClassName=m_szClientWndClassName;
myclass.lpszMenuName=NULL;
myclass.style=CS_HREDRAW | CS_VREDRAW;
if (!RegisterClass(&myclass))
{
MessageBox(NULL,"注册窗口类失败","注册",MB_OK|MB_ICONERROR);
return;
}
m_hwnd=createwindow(m_szClientWndClassName,
m_szClientWndName,
m_WndStyle,
m_x,
m_y,
m_Width,
m_Height,
NULL,
NULL,
m_hInst,
NULL
);
if (m_hwnd==NULL)
{
MessageBox(NULL,"创建窗口失败","",MB_OK|MB_ICONERROR);
return;
}
ShowWindow(m_hwnd,SW_SHOW);
UpdateWindow(m_hwnd);
}
//消息循环
void CClient::MessageLoop(void)
{
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
//窗口过程
//注册用户对话框
INT_PTR CALLBACK RegQQUser(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam);
INT_PTR CALLBACK LogDlgProc(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam);
//全局变量
char g_szUserName[256];//用户输入的用户名
char g_szPassWord[256];//用户输入的密码
UINT client_uPort=6060;//客户端端口号,这个端口号匹配服务器端端口号,PC间通信就是利用这个端口
int len;
int WSA_return;
WSADATA WSAData;
SOCKET client_hSocket;
struct sockaddr_in client_addr;
BOOL bErr;//socket错误
char ClientIP[20];//客户端IP,就是要链接到的服务器端PC的IP,这个IP要访问外部文件来获取
#define CLIENT_MESSAGE WM_USER+200
char ReceiveText[256];
char ShowText[1024];
HWND g_hDlg=NULL;
char ShowText_On_Dlg[1024];
char ShowText_On_Dlg2[1024];
char ReceiveMsg[256];
BOOL lb_CheckLogSuccess=FALSE;//检查登录是否成功
LRESULT CALLBACK CClient::ClientWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(msg)
{
case CLIENT_MESSAGE ://接受信息(因为通行双方才采取的方式是异步方式,必须通过一个消息去接受)
{
switch(lParam)
{
case FD_READ:
{
if (lb_CheckLogSuccess==FALSE)
{
len=recv(client_hSocket,ReceiveText,256,0);
ReceiveText[len]='\0';
SetDlgItemText(hwnd,200,"");
SetDlgItemText(hwnd,200,ReceiveText);
if (strcmp(ReceiveText,"mustfillnameandpassword")==0)
{
MessageBox(hwnd,"用户名和密码必须填写",NULL,NULL);
}
if (strcmp(ReceiveText,"failedlogin")==0)
{
MessageBox(hwnd,"登录失败,请检查用户名和密码是否正确",NULL,NULL);
}
if (strcmp(ReceiveText,"success")==0)
{
lb_CheckLogSuccess=TRUE;
ShowWindow(hwnd,SW_HIDE);
HINSTANCE hInst=(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE);
DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG2),hwnd,LogDlgProc);
}
}
if (lb_CheckLogSuccess==TRUE)//如果登录成功,要将接受的字符信息显示到用户聊天对话框的编辑框中
{
//HWND hShowTextOnDlg=GetDlgItem(g_hDlg,IDC_EDIT1);
len=recv(client_hSocket,ReceiveMsg,256,0);
ReceiveMsg[len]='\0';
strcat(ShowText_On_Dlg2,"\r\n");
strcat(ShowText_On_Dlg2,ReceiveMsg);
SetDlgItemText(g_hDlg,IDC_EDIT3,ShowText_On_Dlg2);
}
return TRUE;
}
case FD_WRITE:
return TRUE;
case FD_CLOSE:
return TRUE;
case FD_CONNECT:
return TRUE;
default:
{
lstrcpy(ShowText,"网络错误,连接失败!");
MessageBox(NULL,ShowText,NULL,NULL);
closesocket(client_hSocket);
return TRUE;
}
}
return FALSE;
}
case WM_LBUTTONDOWN: //当鼠标左键点击时可以拖曳窗口
{
SetFocus(hwnd);
PostMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
return 0;
}
case WM_KEYDOWN:
{
switch(wParam)
{
case VK_ESCAPE:
{
PostQuitMessage(0);
break;
}
}
break;
}
case WM_CREATE:
{
//初始化socket
WSA_return=WSAStartup(0x0002,&WSAData);
if(WSA_return!=0)
{
MessageBox(NULL,"初始化失败!","警告!",MB_OK);
WSACleanup();
}
//创建位图按钮
CBitMapButton *CBitMapButtonAPP1=new CBitMapButton(430,10,25,25,WS_CHILD|WS_VISIBLE|BS_BITMAP|BS_PUSHLIKE|BS_FLAT,101,hwnd,lParam,IDB_BITMAP4);
CBitMapButtonApp1->CreateBitMapButton();
CBitMapButton *CBitMapButtonApp2=new CBitMapButton(460,10,25,25,WS_CHILD|WS_VISIBLE|BS_BITMAP|BS_PUSHLIKE|BS_FLAT,102,hwnd,lParam,IDB_BITMAP3);
CBitMapButtonApp2->CreateBitMapButton();
//创建用户名输入框
HWND hEdit1=CreateWindow("edit",TEXT(""),WS_CHILD|WS_VISIBLE|SS_LEFT|WS_BORDER,200,210,120,25,hwnd,(HMENU)103,((LPCREATESTRUCT)lParam)->hInstance,NULL);
//创建密码输入框
HWND hEdit2=CreateWindow("edit",TEXT(""),WS_CHILD|WS_VISIBLE|SS_LEFT|WS_BORDER,200,250,120,25,hwnd,(HMENU)104,((LPCREATESTRUCT)lParam)->hInstance,NULL);
HWND hEdit4=CreateWindow("edit",TEXT(""),WS_CHILD|WS_VISIBLE|SS_LEFT|WS_BORDER,200,170,120,25,hwnd,(HMENU)110,((LPCREATESTRUCT)lParam)->hInstance,NULL);
HWND hEdit3=CreateWindow("edit",TEXT(""),WS_CHILD|WS_VISIBLE|SS_LEFT|WS_BORDER,50,50,300,100,hwnd,(HMENU)200,((LPCREATESTRUCT)lParam)->hInstance,NULL);
ShowWindow(hEdit3,SW_HIDE);
//创建注册用户按钮
CBitMapButton *CBitMapButtonApp3=new CBitMapButton(350,250,110,25,WS_CHILD|WS_VISIBLE|BS_BITMAP|BS_PUSHLIKE|BS_FLAT,105,hwnd,lParam,IDB_BITMAP5);
CBitMapButtonApp3->CreateBitMapButton();
//创建登录按钮
CBitMapButton *CBitMapButtonApp4=new CBitMapButton(205,280,110,30,WS_CHILD|WS_VISIBLE|BS_BITMAP|BS_PUSHLIKE|BS_FLAT,106,hwnd,lParam,IDB_BITMAP6);
CBitMapButtonApp4->CreateBitMapButton();
// 设置字体参数
LOGFONT LogFont;
::memset(&LogFont, 0, sizeof(LOGFONT));
strcpy(LogFont.lfFaceName,"新宋体");
LogFont.lfWeight = 400;
LogFont.lfHeight = 18; // 字体大小
LogFont.lfCharSet = 134;
LogFont.lfOutPrecision = 3;
LogFont.lfClipPrecision = 2;
LogFont.lfOrientation = 45;
LogFont.lfQuality = 1;
LogFont.lfPitchAndFamily = 2;
// 创建字体
HFONT hFont = CreateFontIndirect(&LogFont);
// 设置控件字体
::SendMessage(hEdit1, WM_SETFONT, (WPARAM)hFont, 0);
::SendMessage(hEdit2, WM_SETFONT, (WPARAM)hFont, 0);
delete CBitMapButtonApp1;
delete CBitMapButtonApp2;
delete CBitMapButtonApp3;
delete CBitMapButtonApp4;
return 0;
}
case WM_CLOSE:
{
////销毁socket资源
//closesocket(client_hSocket);
//WSACleanup();
//PostQuitMessage(0);
return 0;
}
case WM_DESTROY:
{
////销毁socket资源
//closesocket(client_hSocket);
//WSACleanup();
//PostQuitMessage(0);
return 0;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case 101:
{
ShowWindow(hwnd, SW_MiniMIZE);
break;
}
case 102:
{
PostQuitMessage(0);
break;
}
case 105://注册
{
//注册用户要弹出一个对话框,让用户区填写注册的个人信息,包括用户名和密码
//然后将获取的用户名和密码通过网络获取让服务器端接收并且在服务器端将信息填入数据库
HINSTANCE hInst=(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE);
DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG1),hwnd,RegQQUser);
break;
}
case 106://登录
{
//登录服务器时要先将用户填写的用户名和密码获取到服务器端,并且在服务器端进行匹配
//匹配成功方可让用户进如聊天室
//将获取的信息发送到服务器端进行检测
//先要确定能够连接到服务器端IP: 172.21.247.173
//先要获取服务器IP
GetDlgItemText(hwnd,110,ClientIP,20);
if (strcmp(ClientIP,"")==0)
{
MessageBox(hwnd,"请先填写服务器IP地址","",MB_OK);
break;
}
//配置
if(client_hSocket!=0)
{
closesocket(client_hSocket);
client_hSocket=0;
}
if(client_hSocket==0)
{
if((client_hSocket=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR)
{
MessageBox(NULL,"建立套接字失败!","警告!",MB_OK);
}
if(WSAAsyncSelect(client_hSocket,hwnd,CLIENT_MESSAGE,FD_READ|FD_WRITE|FD_CLOSE|FD_CONNECT)>0)
{
MessageBox(NULL,"异步模式创建失败!","警告!",MB_OK);
}
}
client_addr.sin_family=AF_INET;
client_addr.sin_addr.S_un.S_addr=inet_addr(ClientIP);
client_addr.sin_port=htons((u_short)client_uPort);
int con;
con=connect(client_hSocket,(LPSOCKADDR)&client_addr,sizeof(client_addr));
if (con!=0)
{
MessageBox(NULL,"建立连接成功",NULL,NULL);
}
else
{
MessageBox(NULL,"建立连接失败",NULL,NULL);
}
//Sleep(5000);
//将获取的用户名和密码发送给服务器端
GetDlgItemText(hwnd,103,g_szUserName,256);
GetDlgItemText(hwnd,104,g_szPassWord,256);
//向服务器发送用户名和密码
int nerr;
int nerr1;
nerr=send(client_hSocket,g_szUserName,256,0);
nerr1=send(client_hSocket,g_szPassWord,256,0);
if (nerr==SOCKET_ERROR)
{
MessageBox(hwnd,"发送用户名失败",NULL,NULL);
}
if (nerr!=SOCKET_ERROR)
{
MessageBox(hwnd,"发送用户名成功",NULL,NULL);
}
if (nerr1==SOCKET_ERROR)
{
MessageBox(hwnd,"发送用户密码失败",NULL,NULL);
}
if (nerr1!=SOCKET_ERROR)
{
MessageBox(hwnd,"发送用户密码成功",NULL,NULL);
}
break;
}
}
break;
}
case WM_eraseBKGND:
{
return 0;
}
case WM_PAINT:
{
hdc=BeginPaint(hwnd,&ps);
HDC hMemDC=createcompatibledc(hdc);
RECT rect;
GetClientRect(hwnd,&rect);
HBITMAP hMemBM=CreateCompatibleBitmap(hdc,rect.right-rect.left,rect.bottom-rect.top);
SelectObject(hMemDC,hMemBM);
static Image *image=NULL;
if (image==NULL)
{
image=Image::FromFile(L"..\\res\\log.PNG");
}
Graphics g(hMemDC);
g.DrawImage(image,0,0,image->GetWidth(),image->GetHeight());
BitBlt(hdc,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,hMemDC,0,0,SRCCOPY);
ReleaseDC(hwnd,hMemDC);
DeleteObject(hMemBM);
EndPaint(hwnd,&ps);
return 0;
}
case WM_SIZE:
{
break;
}
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}
void RegUserInfo(HWND hwnd,const char UserName[],const char PassWord[]);//用户注册
INT_PTR CALLBACK RegQQUser(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(msg)
{
case WM_LBUTTONDOWN: //当鼠标左键点击时可以拖曳窗口
{
SetFocus(hDlg);
PostMessage(hDlg, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
return 0;
}
case WM_INITDIALOG:
{
//创建按钮
Gdiplus::GdiplusStartup(&m_pGdiToken,&m_gdiplusStartupInput,NULL);
RECT rect;
HWND hparent;
hParent=::FindWindowW(L"myserverclass",L"QQ聊天室_天策版");
GetWindowRect(hParent,&rect);
SetWindowPos(hDlg,NULL,rect.right,rect.top,300,320,SWP_SHOWWINDOW);
HINSTANCE hInst=(HINSTANCE)GetWindowLong(hDlg,GWL_HINSTANCE);
HWND hBtn=GetDlgItem(hDlg,IDC_BUTTON1);
HBITMAP hbmp1=LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP7));
SendMessage(hBtn, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp1);
// 设置字体参数
LOGFONT LogFont;
::memset(&LogFont, 0, sizeof(LOGFONT));
strcpy(LogFont.lfFaceName,"新宋体");
LogFont.lfWeight = 400;
LogFont.lfHeight = 18; // 字体大小
LogFont.lfCharSet = 134;
LogFont.lfOutPrecision = 3;
LogFont.lfClipPrecision = 2;
LogFont.lfOrientation = 45;
LogFont.lfQuality = 1;
LogFont.lfPitchAndFamily = 2;
// 创建字体
HFONT hFont = CreateFontIndirect(&LogFont);
// 设置控件字体
HWND hEdit1=GetDlgItem(hDlg,IDC_EDIT1);
HWND hEdit2=GetDlgItem(hDlg,IDC_EDIT2);
::SendMessage(hEdit1, WM_SETFONT, (WPARAM)hFont, 0);
::SendMessage(hEdit2, WM_SETFONT, (WPARAM)hFont, 0);
HWND hBtn2=GetDlgItem(hDlg,IDC_BUTTON2);
HBITMAP hbmp2=LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP10));
SendMessage(hBtn2, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp2);
HWND hBtn3=GetDlgItem(hDlg,IDC_BUTTON3);
HBITMAP hbmp3=LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP9));
SendMessage(hBtn3, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp3);
break;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDOK:
case IDCANCEL:
case IDC_BUTTON1:
case IDC_BUTTON3:
{
Gdiplus::GdiplusShutdown(m_pGdiToken);
EndDialog(hDlg,NULL);
break;
}
case IDC_BUTTON2://确认注册,将用户名和密码送至服务端
{
break;
}
}
break;
}
case WM_ERASEBKGND:
{
return 0;
}
case WM_PAINT:
{
hdc=BeginPaint(hDlg,&ps);
HDC hMemDC=CreateCompatibleDC(hdc);
RECT rect;
GetClientRect(hDlg,&rect);
HBITMAP hMemBM=CreateCompatibleBitmap(hdc,rect.right-rect.left,rect.bottom-rect.top);
SelectObject(hMemDC,hMemBM);
static Image *image=NULL;
if (image==NULL)
{
image=Image::FromFile(L"..\\res\\reg.jpg");
}
Graphics g(hMemDC);
g.DrawImage(image,0,0,image->GetWidth(),image->GetHeight());
BitBlt(hdc,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,hMemDC,0,0,SRCCOPY);
ReleaseDC(hDlg,hMemDC);
DeleteObject(hMemBM);
EndPaint(hDlg,&ps);
return 0;
}
}
return (INT_PTR)FALSE;
}
INT_PTR CALLBACK LogDlgProc(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_INITDIALOG:
{
g_hDlg=hDlg;
HINSTANCE hInst=(HINSTANCE)GetWindowLong(hDlg,GWL_HINSTANCE);
HWND hBtn1=GetDlgItem(hDlg,IDC_BUTTON2);
HBITMAP hbmp1=LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP2));
SendMessage(hBtn1, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp1);
HWND hBtn2=GetDlgItem(hDlg,IDC_BUTTON1);
HBITMAP hbmp2=LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP3));
SendMessage(hBtn2, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp2);
// 设置字体参数
LOGFONT LogFont;
::memset(&LogFont, 0, sizeof(LOGFONT));
strcpy(LogFont.lfFaceName,"新宋体");
LogFont.lfWeight = 400;
LogFont.lfHeight = 18; // 字体大小
LogFont.lfCharSet = 134;
LogFont.lfOutPrecision = 3;
LogFont.lfClipPrecision = 2;
LogFont.lfOrientation = 45;
LogFont.lfQuality = 1;
LogFont.lfPitchAndFamily = 2;
// 创建字体
HFONT hFont = CreateFontIndirect(&LogFont);
HWND hEdit1=GetDlgItem(hDlg,IDC_EDIT1);
HWND hEdit2=GetDlgItem(hDlg,IDC_EDIT2);
::SendMessage(hEdit1, WM_SETFONT, (WPARAM)hFont, 0);
::SendMessage(hEdit2, WM_SETFONT, (WPARAM)hFont, 0);
return (INT_PTR)TRUE;
}
case WM_LBUTTONDOWN: //当鼠标左键点击时可以拖曳窗口
{
SetFocus(hDlg);
PostMessage(hDlg, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
return 0;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDCANCEL:
{
closesocket(client_hSocket);
WSACleanup();
EndDialog(hDlg,TRUE);
break;
}
case IDC_BUTTON1:
{
closesocket(client_hSocket);
WSACleanup();
EndDialog(hDlg,NULL);
PostQuitMessage(0);
break;
}
case IDC_BUTTON3:
{
char InputText[256];
GetDlgItemText(hDlg,IDC_EDIT2,InputText,256);
strcat(ShowText_On_Dlg,"\r\n");
strcat(ShowText_On_Dlg,g_szUserName);
strcat(ShowText_On_Dlg,":");
strcat(ShowText_On_Dlg,InputText);
strcat(ShowText_On_Dlg,"\r\n");
SetDlgItemText(hDlg,IDC_EDIT1,ShowText_On_Dlg);
send(client_hSocket,InputText,256,0);
strcpy(InputText,"");
SetDlgItemText(hDlg,IDC_EDIT2,InputText);
break;
}
}
break;
}
}
return FALSE;
}
效果图:
相关阅读
一、基本概念 1.二叉排序树 二叉排序树(Binary sort tree,BST),又称为二叉查找树,或者是一棵空树;或者是具有下列性质的二叉树: (1)若
第一步,注册一个有趣味的微博名字,如减肥瘦身百科,护肤美妆百科,美食营养百科。这样做的目的是便于搜索,目前也是女生关注最多的话题。
目录 题目描述 输入/输出描述 解决思路 代码 代码走读 传送门 测试用例 1. 输入的数据都是整型 2. 输入的数据存在非法字符 题
写一个简易的socks5代理服务器,负责转发网络数据包,要能够使用它来上网。 SOCKS5 是一个代理协议,它在使用TCP/IP协议通讯的前端机器
这是一个非常有意思的类,看下面的代码:CountDownLatch countDownLatch = new CountDownLatch(1); new Thread(new Runnable() {