当前位置:网站首页>QQ version network chat room complete project + MFC / C + + / C (changing server IP can realize communication between different computers)

QQ version network chat room complete project + MFC / C + + / C (changing server IP can realize communication between different computers)

2020-12-06 09:17:21 osc_ wuji6g86

Resources to address 1

https://github.com/Msrumo/QChatRoom

Resources to address 2

https://gitee.com/it-future/QChatRoom

Project brief introduction

Statement :: Use the server IP To realize the communication between different clients , There may be some problems with this code , It needs to be debugged and used by oneself !
Does not mean that this source code can directly achieve network communication ! Only local area network does not make mistakes !

Design function

1.ChatRoom imitation QQ The interface realizes LAN message exchange ;
2. Users sign up to get ID, These will be saved in mysql In the database , You can customize your avatar 、 Nickname, etc ;
3. After logging in , Select private message mode , In the friends list, you can double-click to select a friend , To have a private chat ;
4. Group talk about the world , Can communicate with all online users in the LAN ;
5. The main user interface has additional settings Bing Web search function , For user's use .



Initialize socket :
Socket Create socket :af Address family tcp/IP All are AF_INET
Streaming sockets are TCP, The packet socket is UDP
0 Choose the right protocol


bind The local address is associated with the socket Socket , Pointer address sockaddr( Contains IP Address , Port number ), length

Create thread
Createthread The third is the thread function The first 4 Parameters passed in for the thread LP For long hands ( Use structs to pass in multiple values )

Thread functions ( Use static ) The softening function belongs to the inner itself
Use an endless loop Constantly accept recvfrom The second parameter is to store data The fifth parameter is used to store the address information for sending messages (sockaddr)
Postmessage Send the message back to the dialog The message is the message in response to the message The second parameter is the message The last two are parameters

Server side part of the code

// Respond to client information 
LRESULT CQServerDlg::OnSocket(WPARAM wParam, LPARAM lParam)
{
   
   
	CMySocket* sock = (CMySocket*)wParam;
	CMySocket* c;

	SOCKADDR_IN sockAddr;
	int nSize = sizeof(sockAddr);
	BOOL res;

	switch (lParam)
	{
   
   
		// New connection message 
	case ACCEPT:
		c = new CMySocket;
		c->AttachCWnd(this);

		res = sock->Accept(*c, (SOCKADDR*)&sockAddr, &nSize);
		if (res == FALSE)
		{
   
   
			MessageBox(_T("Accept Error!"));
		}
		break;
		// Turn off the connection message 
	case CLOSE:
		ClosePlayer(sock);
		break;
		// Received data message , Process messages and send 
	case RETURN:
		ParserPkt(sock);
		break;
	}
	return 1;
}

Client response part of the code

//Socket Message response function 
LRESULT CQClientDlg::OnSocket(WPARAM wParam, LPARAM lParam)
{
   
   
	char	pkt[4096];
	memset(pkt, 0, 4096);

	LVFINDINFO   info;
	LVITEM lvitem;

	switch (lParam)
	{
   
   
	case RETURN:
		m_socket.Receive(pkt, 4096);

		switch (pkt[0])
		{
   
   
		case 0x11:
			// Connection information 
			pName[curNum] = pkt + 2;
			curNum++;
			m_showMsg += pkt + 2;
			m_showMsg += "  Enter the Liaoshi .\r\n";

			lvitem.mask = LVIF_IMAGE | LVIF_TEXT;
			lvitem.iItem = curNum;
			lvitem.pszText = pkt + 2;
			lvitem.iImage = pkt[1] - 1;
			lvitem.iSubItem = 0;

			m_list.InsertItem(&lvitem);

			break;
			// Added user information 
		case 0x31:
			pName[curNum] = pkt + 2;
			curNum++;

			lvitem.mask = LVIF_IMAGE | LVIF_TEXT;
			lvitem.iItem = curNum;
			lvitem.pszText = pkt + 2;
			lvitem.iImage = pkt[1] - 0x31;
			lvitem.iSubItem = 0;

			m_list.InsertItem(&lvitem);
			break;
			// sign out 
		case 0x41:
			//pkt + 1 Save the user name 
			m_showMsg += pkt + 1;
			m_showMsg += "  Quit the chat room \r\n";

			info.flags = LVFI_PARTIAL | LVFI_STRING;
			info.psz = pkt + 1;
			int item;
			item = m_list.FindItem(&info);

			if (item != -1)
			{
   
   
				m_list.DeleteItem(item);
			}
			break;
		default:
			// For messages without any command , Directly in the message box 
			m_showMsg += pkt + 1;
		}

		UpdateData(false);
		break;

	case CLOSE:
		MessageBox(" The server is down !");
		break;
	}
	return 1;
}

Database connection

// Connect MYSQL database 
BOOL CQClientDlg::ConnectDB()
{
   
   
	// Initialize database 
	mysql_init(&m_mysql);
	// Set database encoding format 
	mysql_options(&m_mysql, MYSQL_SET_CHARSET_NAME, "gbk");
	// Connect to database 
	if (!mysql_real_connect(&m_mysql, host, user, pass, dbname, port, NULL, 0))
		return FALSE;
	return TRUE;
}
void CQClientDlg::FreeConnect() {
   
   
	mysql_free_result(m_res);
	mysql_close(&m_mysql);
}
// Query for data 
BOOL CQClientDlg::SelectDB()
{
   
   
	UpdateData(TRUE);

	char query[150];

	  // Format the data to a string 
	sprintf(query, "select * from Client");
	// Set the encoding format 
	mysql_query(&m_mysql, "set names gbk");

	if (mysql_query(&m_mysql, query)) {
   
   
	/*	printf("Query failed (%s)\n", mysql_error(&m_mysql));*/
		return false;
	}
	else {
   
   
		printf("query success\n");
	}
	m_res = mysql_store_result(&m_mysql);
	if (!m_res) {
   
   
	/*	printf("Couldn't get result from %s\n", mysql_error(&m_mysql));*/
		return false;
	}
	printf("number of dataline returned: %d\n", mysql_affected_rows(&m_mysql));

	int row = 0;
	// To get the results 
	while (m_row = mysql_fetch_row(m_res)) {
   
   
		count++;
		m_data[row][0] = m_row[0];
		m_data[row][1] = m_row[1];
		m_data[row++][2] = m_row[2];
	}
	return TRUE;
}

theory ~

The main process of writing

Initialize socket :
Socket Create socket :af Address family tcp/IP All are AF_INET
Streaming sockets are TCP, The packet socket is UDP
0 Choose the right protocol


bind The local address is associated with the socket Socket , Pointer address sockaddr( Contains IP Address , Port number ), length

Create thread
Createthread The third is the thread function The first 4 Parameters passed in for the thread LP For long hands ( Use structs to pass in multiple values )

Thread functions ( Use static ) The softening function belongs to the inner itself
Use an endless loop Constantly accept recvfrom The second parameter is to store data The fifth parameter is used to store the address information for sending messages (sockaddr)
Postmessage Send the message back to the dialog The message is the message in response to the message The second parameter is the message The last two are parameters
CSocket class :


CSocket Class is from CAsyncsocket Derived from , It inherited CAsyncsocket Yes WindowsSockets API Encapsulation . And CAsyncsocket Object comparison ,CSocket The object represents WindowsSockets API A higher level of abstraction .CSocket With the class CSocketFile and CArchive Together to manage the sending and receiving of data .
One CSocket Objects also support blocking , This is for CArchive Is necessary for synchronous operation . Block operation function , such as Receive,Send,ReceiveFrom,SendTo, and Accept( from CAsyncsocket inherited ), None of them returned a CSocket Object WSAEWOULDBLOCK error . Instead, , These functions wait for , Until the operation is complete . in addition , When one of these functions is blocked , If called CancelBlockingCall, The original call will be due to WSAEINTR To terminate by mistake .
Use a CSocket object , Call constructor , And then call Create To create the foundation Slot handle ( Slot type ).Create The default parameter of creates a slot , But if you don't use one CArchive Object to use this slot , You can specify a parameter to create a packet Slot instead of , Or create a server slot with a specified port . Use on the client side Connect, Then the server uses Accept To connect to a customer slot . Then create another CSocketFile object , And in CSocketFile To connect it to CSocket On the object . We'll go on with the , Create a CArchive Object is used to send data , One to receive data ( if necessary ), And then in CArchive The constructor will match them with CSocketFile Object connection . When communication is complete , The destruction CArchive,CSocketFile,CSocket object .

Tcp The process is

Server side :
The first is to use WSAstartup Load socket , And set in the project settings ws2_32.lib file

In the use of socket Create socket , The datagram
Bind

Recvfrom For receiving data

Sendto

Experience and experience :
There is no port number defined on the client side , Each creation socket A free port number will be added to it at random

Example show

Server side :
 Insert picture description here

Login box :
 Insert picture description here
main interface :
 Insert picture description here
Chat box :
 Insert picture description here




If possible, try to change the server IP It can realize communication between different machines , If you have any questions, please contact us !
Source code to download and use ~~

版权声明
本文为[osc_ wuji6g86]所创,转载请带上原文链接,感谢
https://chowdera.com/2020/12/202012060916390455.html