⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socketcommdlg.cpp

📁 VisualC++通信编程工程实例精解 Chapter 2 Example 1 MSCOMM控件编程实例 Example 2 基于Windows API的虚拟终端实现 Example 3
💻 CPP
字号:
// SocketCommDlg.cpp : implementation file
//

#include "stdafx.h"
#include "SocketComm.h"
#include "SocketCommDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

////////////////////////////////////
//添加2个头文件,实现CTime类
///////////////////////////////////
#include "time.h"
#include "sys/timeb.h"
///////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSocketCommDlg dialog

CSocketCommDlg::CSocketCommDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSocketCommDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSocketCommDlg)
	m_uPort = 4000;
	m_Type = 0;
	m_sShowText = _T("");
	m_LocalState = _T("");
	m_sInputText = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CSocketCommDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSocketCommDlg)
	DDX_Control(pDX, IDC_REMOTESTATE, m_RemoteState);
	DDX_Control(pDX, IDC_SERVERIP, m_ServerIP);
	DDX_Text(pDX, IDC_PORT, m_uPort);
	DDX_Radio(pDX, IDC_SERVER, m_Type);
	DDX_Text(pDX, IDC_SHOWTEXT, m_sShowText);
	DDX_Text(pDX, IDC_LOCALSTATE, m_LocalState);
	DDX_Text(pDX, IDC_INPUTTEXT, m_sInputText);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSocketCommDlg, CDialog)
	//{{AFX_MSG_MAP(CSocketCommDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_SERVER, OnServer)
	ON_BN_CLICKED(IDC_CLIENT, OnClient)
	ON_MESSAGE(SER_MESSAGE,OnServerMessage)
	ON_MESSAGE(CLI_MESSAGE,OnClientMessage)
	ON_BN_CLICKED(IDC_STARTLINK, OnStartlink)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_STOP, OnStop)
	ON_BN_CLICKED(IDC_SEND, OnSend)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSocketCommDlg message handlers

BOOL CSocketCommDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	//2006.08.12.21:35
	m_ServerIP.EnableWindow(false);
	//2006.08.12.23:55 设置定时器 用于显示连接 命令时间
	SetTimer(1,1000,NULL);
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CSocketCommDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CSocketCommDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CSocketCommDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CSocketCommDlg::OnServer() 
{
	// TODO: Add your control notification handler code here
	m_Type=0;
	m_ServerIP.EnableWindow(false);
	GetDlgItem(IDC_STARTLINK)->SetWindowText("启动服务器");
	(AfxGetMainWnd())->SetWindowText("服务器");	

}

void CSocketCommDlg::OnClient() 
{
	// TODO: Add your control notification handler code here
	m_Type=1;
	m_ServerIP.EnableWindow(true);
	GetDlgItem(IDC_STARTLINK)->SetWindowText("连接服务器");
	(AfxGetMainWnd())->SetWindowText("客户机");		
}

void CSocketCommDlg::OnStartlink() 
{
	// TODO: Add your control notification handler code here
	if (!m_Type)  //服务器:启动服务器
	{
		if(m_server.InitAndListen(this->m_hWnd,m_uPort)==FALSE)
		{
			return;
		}
		else
		{
			m_bInit=TRUE;
			m_bClient=FALSE;
			//m_sShowText="Server has been set ok!\n";
			CString m_StateInfo;
			m_StateInfo.Format("%s:服务器已启动",DateTime);
			GetDlgItem(IDC_LOCALSTATE)->SetWindowText(m_StateInfo);
		}
	}
	else          //客户机:连接服务器
	{
		BYTE  f0,f1,f2,f3;
		m_ServerIP.GetAddress(f0,f1,f2,f3);
		CString add;
		add.Format("%d.%d.%d.%d",f0,f1,f2,f3);
		//客户端连接初始化
		if(m_client.InitAndConnet(m_hWnd,m_uPort,add)==FALSE)
			return;	
	}
	
}

/////////////////////////////////////////////////////////////////
//Server消息相应函数
LRESULT CSocketCommDlg::OnServerMessage(WPARAM wParam, LPARAM lParam)
{

	SOCKET socket,ts;
	int length,i,j;
	CString str="";
	CEdit * output=NULL;
	char s[1024];
	int len;
	CString ClientInto;
	switch(lParam)
	{
		case FD_ACCEPT:
			socket= accept(m_server.m_hSocket,NULL,NULL);

			//以下程序段是获得远程的IP和端口号
			char szIP[100];
			UINT uPort;

			sockaddr sockAddr;
			len = sizeof(struct sockaddr);
			getpeername(socket, &sockAddr, &len);
			sockaddr_in inAddr;
			memcpy(&inAddr, &sockAddr, sizeof(sockaddr));
			strcpy(szIP, inet_ntoa(inAddr.sin_addr));
			uPort = inAddr.sin_port;

			length=m_connectionList.GetCount();
/*			
			for(i=0;i<length;i++)
			{
				ts=m_connectionList.GetAt(m_connectionList.FindIndex(i));
				s[0]=NULL;
				strcat(s,"一个游客进入了聊天室");
				send(ts,s,strlen(s),0);
			}
*/			
			//m_sShowText+="\n";
			//m_sShowText+="一个游客进入了聊天室了";			
			//GetDlgItem(IDC_SHOWTEXT)->SetWindowText(m_sShowText);
			//GetDlgItem(IDC_SHOWTEXT)->SetWindowText(szIP);	
			ClientInto.Format("%s:<%s:%d>(Socket<%d>)连接服务器",DateTime,szIP,uPort,socket);
			m_RemoteState.AddString(ClientInto);

			output=(CEdit *)GetDlgItem(IDC_SHOWTEXT);
			//随时跟踪滚动条的位置
			output->LineScroll(output->GetLineCount());
			m_connectionList.AddHead(socket);
			return 0;

		case FD_READ:
			length=m_connectionList.GetCount();
			for(i=0;i<length;i++)
			{
				socket=m_connectionList.GetAt(m_connectionList.FindIndex(i));
				if(socket==wParam)
				{
					//服务器收到消息 解码?~?~?~
					len=recv(socket,s,1024,0);
					s[len]=NULL;
					//s即为接收得信息

					//将一个客户端发送的消息传递到其他客户端去
			/*	
					for(j=0;j<length;j++)
					{
						socket=m_connectionList.GetAt(m_connectionList.FindIndex(j));
						if(socket!=wParam)
						{
							send(socket,s,strlen(s),0);
						}
					}
			*/		
					m_sShowText=m_sShowText+s;
					GetDlgItem(IDC_SHOWTEXT)->SetWindowText(m_sShowText);
					CEdit * output=(CEdit *)GetDlgItem(IDC_SHOWTEXT);
					//随时跟踪滚动条的位置
					output->LineScroll(output->GetLineCount());
					return 0;
				}
			}
			return 0;

		case FD_WRITE:
			return 0;

		case FD_CLOSE:
			return 0;

		default:
			//客户机退出时服务器端消息
			//m_sShowText=m_sShowText+"An networking error has occured with a client";
			//GetDlgItem(IDC_SHOWTEXT)->SetWindowText(m_sShowText);

			len = sizeof(struct sockaddr);
			getpeername(wParam, &sockAddr, &len);
			memcpy(&inAddr, &sockAddr, sizeof(sockaddr));
			strcpy(szIP, inet_ntoa(inAddr.sin_addr));
			uPort = inAddr.sin_port;


			ClientInto.Format("%s:<%s:%d>(Socket<%d>)断开与服务器的连接",DateTime,szIP,uPort,wParam);
			m_RemoteState.AddString(ClientInto);

			CEdit * output=(CEdit *)GetDlgItem(IDC_SHOWTEXT);
			//随时跟踪滚动条的位置
			output->LineScroll(output->GetLineCount());
			return 0;
	}
}

LRESULT CSocketCommDlg::OnClientMessage(WPARAM wParam, LPARAM lParam)
{
	CEdit * output=NULL;
	char s[1024];
	int len;
	CString RemoteState;
	switch(lParam)
	{
		case FD_CONNECT:
			len=GetLastError();
			if(len!=0)
			{
				AfxMessageBox("连接错误");
			}
			else
			{
				m_bInit=TRUE;
				m_bClient=TRUE;
				//m_sShowText="Having connected to server!\n";
				//GetDlgItem(IDC_SHOWTEXT)->SetWindowText(m_sShowText);
				m_LocalState.Format("%s:连接服务器",DateTime);
				GetDlgItem(IDC_LOCALSTATE)->SetWindowText(m_LocalState);
			}
			return 0;
		case FD_READ:
			//收到服务器端的消息
			len=recv(m_client.m_hSocket,s,1024,0);
			s[len]=NULL;
			m_sShowText+=s;
			//随时跟踪滚动条的位置 
			output=(CEdit *)GetDlgItem(IDC_SHOWTEXT);
			output->SetWindowText(m_sShowText);
			output->LineScroll(output->GetLineCount());
			return 0;
		case FD_WRITE:
			return 0;
		case FD_CLOSE:
			return 0;
		default:
			//服务器退出时客户机端消息
			//output=(CEdit *)GetDlgItem(IDC_SHOWTEXT);
			//output->SetWindowText("An network error has occured,the connection is dropped");
			RemoteState.Format("%s:服务器关闭",DateTime);
			m_RemoteState.AddString(RemoteState);
			closesocket(m_client.m_hSocket);
			m_bInit=false;
			return 0;
	}
}

void CSocketCommDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	CTime ct=CTime::GetCurrentTime();
	CString ShowDate,ShowTime;
	ShowDate.Format("%4d年%d月%d日",ct.GetYear(),ct.GetMonth(),ct.GetDay());
	ShowTime.Format("%2d:%02d:%02d",ct.GetHour(),ct.GetMinute(),ct.GetSecond());
	DateTime.Format("%s-%s",ShowDate,ShowTime);
	
	CDialog::OnTimer(nIDEvent);
}

void CSocketCommDlg::OnStop() 
{
	// TODO: Add your control notification handler code here
	if (!m_Type)
	{
		closesocket(m_server.m_hSocket);
		
	}
	else
	{
		closesocket(m_client.m_hSocket);
	
	}

}

void CSocketCommDlg::OnSend() 
{
	// TODO: Add your control notification handler code here
	if(!m_bInit)
	{
		AfxMessageBox("The session has not been set correctly");
		return;
	}
	CString in;
	GetDlgItem(IDC_INPUTTEXT)->GetWindowText(in);
	//输入框中只有回车键被按下,所以不发送回车键字符
	if(in.GetLength()<1)
	{
		return;
	}

//	if(in.GetAt(in.GetLength()-1)=='\n')
//	{
		//in.TrimRight(" ")用来消去无用的空格键字符
		in.TrimRight(" ");
		//将输入框中的字符清空,表示字符已经被发送
		GetDlgItem(IDC_INPUTTEXT)->SetWindowText("");
		if(in.GetLength()>2)
		{
			m_sShowText+=in;
			//将输入的话显示到显示窗口中
			GetDlgItem(IDC_SHOWTEXT)->SetWindowText(m_sShowText);		
			CEdit * output=(CEdit *)GetDlgItem(IDC_SHOWTEXT);
			//随时跟踪滚动条的位置
			output->LineScroll(output->GetLineCount());

			//服务器端
			if(!m_bClient)
			{
				int length=m_connectionList.GetCount();
				SOCKET  socket;
				for(int i=0;i<length;i++)
				{
					socket=m_connectionList.GetAt(m_connectionList.FindIndex(i));
					send(socket,in.GetBuffer(0),in.GetLength(),0);
				}
			}
			//客户端
			else
			{
				m_client.SendString(in);
			}
		}
//	}
		
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -