Source code analysis 4-send a message and source code

Source: Internet
Author: User
Tags sendmsg

Source code analysis 4-send a message and source code

Reprinted please indicate the source:Http://blog.csdn.net/mxway/article/details/44569831
This article is based on the source code v2.06
Fliggy is a software that works on a LAN. It supports message sending and file transmission between different devices in the LAN (udp is used for message sending and tcp is used for file transmission ).
Transmission of messages and files is carried out in the send dialog box of the Flying Pigeon mail, and the send dialog box is opened by double-clicking the icon from the tray (win7 system) to the taskbar. The icon that is dragged to the taskbar is the main window of the Flying Pigeon family. The source code is the TMainWin class in Mainwin. cpp. The following section describes how to process double-click events in the TMainWin class. For more information about how to process events with double-click events by using EventButton, see article 2-message mechanism.

BOOL TMainWin::EventButton(UINT uMsg, int nHitTest, POINTS pos){    switch (uMsg)    {         ...    case WM_LBUTTONDBLCLK:    case WM_NCLBUTTONDBLCLK:        if (cfg->OneClickPopup == FALSE)            SendDlgOpen();        return  TRUE;         ...    }}BOOL TMainWin::SendDlgOpen(HWND hRecvWnd, MsgBuf *msg){    TSendDlg *sendDlg;    ...    if ((sendDlg = new TSendDlg(msgMng, shareMng, &hosts, cfg, logmng, hRecvWnd, msg)) == NULL)        return  FALSE;    sendList.AddObj(sendDlg);    sendDlg->Create(), sendDlg->Show();    ...}BOOL TDlg::Create(HINSTANCE hInstance){    TApp::AddWin(this);    if ((hWnd = ::CreateDialog(hInstance ? hInstance : TApp::hI, resId ? (LPCSTR)resId : resName, parent ? parent->hWnd : NULL, (DLGPROC)TApp::WinProc)) == NULL)        return  TApp::DelWin(this), FALSE;    else        return  TRUE;}

The message sending dialog box is similar to the following:

In the send dialog box, enter the content to be sent in the edit box, select the object to be sent in the user list, and click send to send the message to the other party. You can choose whether to encrypt the sent message. to simplify the problem, only the simplest message sending is analyzed.

1. Sending format of the fliggy text message
Data Package unique ID: User name: Machine name: Command: real message
(1) The fliggy biography version is a macro definition.

#define IPMSG_VERSION           0x0001

(2) The unique data packet number is automatically generated by the fliggy data transfer program.
(3) User name: if you do not set your own name using the Flying Pigeon text, the user name currently logged on to the system is used by default.
(4) machine name. The name of the device is the name of the computer set by the PC.
(5) The command is a 32-bit unsigned number. Its function is divided into two parts. The last eight digits are used for required commands, indicating what the other party needs after receiving the command, for example, a user can publish a message, exit a notification, or send a message. The first 24 bits are used for optional commands, such as encrypting messages and obtaining encrypted keys.
(6) Real messages. This is the information to be sent to the other party, including the messages to be sent to the other party and the file information to be sent to the other party.
The code for generating messages in the preceding format is as follows:

ULONG MsgMng: MakeMsg (char * buf, int _ packetNo, ULONG command, const char * msg, const char * exMsg, int * packet_len) {int len, ex_len = exMsg? Strlen (exMsg) + 1: 0, max_len = MAX_UDPBUF; if (packet_len = NULL) packet_len = & len; // version: data packet No.: User name: Device Name: command: * packet_len = wsprintf (buf, "% d: % ld: % s: % ld:", IPMSG_VERSION, _ packetNo, local. userName, local. hostName, command); if (ex_len + * packet_len + 1> = MAX_UDPBUF) ex_len = 0; max_len-= ex_len; if (msg! = NULL) // LocalNewLineToUnix converts \ r \ n to \ n * packet_len + = LocalNewLineToUnix (msg, buf + * packet_len, max_len-* packet_len); (* packet_len) ++; if (ex_len) {// if there is an additional message (such as sending a file and sending an additional message at the same time) memcpy (buf + * packet_len, exMsg, ex_len ); * packet_len + = ex_len;} return _ packetNo ;}

Ii. Message sending
The code for clicking the send button is as follows:

BOOL TSendDlg: EvCommand (WORD wyycode, WORD wID, LPARAM hWndCtl) {switch (wID) {case IDOK :... sendMsg ();...}} BOOL TSendDlg: SendMsg (void) {command = IPMSG_SENDMSG | IPMSG_SENDCHECKOPT; // obtain the selected number if (sendEntryNum = (int) SendDlgItemMessage (HOST_LIST, LVM_GETSELECTEDCOUNT, 0, 0 )) <= 0 | (sendEntry = new SendEntry [sendEntryNum]) = NULL) return FALSE; // get the message data to be sent GetDlgItemText (SEND_EDIT, msg. m SgBuf, MAX_UDPBUF); int storeCnt = 0, status = 0, cnt; int localStatus = sendEntryNum <= cfg-> EncryptNum & (cfg-> pubKey. key () | cfg-> smallPubKey. key ())? IPMSG_ENCRYPTOPT: 0; // obtain the information of the selected host. The host information is for (cnt = 0; cnt <memberCnt & storeCnt <sendEntryNum; cnt ++) transmitted by TMainWin) {if (SendDlgItemMessage (HOST_LIST, LVM_GETITEMSTATE, cnt, LVIS_SELECTED) & LVIS_SELECTED) = 0) continue; char hostStr [MAX_LISTBUF]; Host * host = hostArray [cnt]; sendEntry * entry = & sendEntry [storeCnt ++]; // encrypt the sent message status | = host-> hostStatus & IPMSG_ENCRYPTOPT; MakeListStrin G (cfg, host, hostStr); logmng-> WriteSendHead (hostStr); entry-> SetHost (host); entry-> SetStatus (localStatus & host-> hostStatus )? Host-> pubKey. Key () = NULL? ST_GETCRYPT: ST_MAKECRYPTMSG: ST_MAKEMSG); entry-> SetCommand (command | (entry-> Status () = ST_MAKEMSG? 0: IPMSG_ENCRYPTOPT);} // The message sent is too long to be truncated msg. msgBuf [MAX_CRYPTLEN] = 0; if (status & = localStatus) command | = IPMSG_ENCRYPTOPT; logmng-> WriteSendMsg (msg. msgBuf, command, cmdinfo); if (cmdinfo & cmdinfo-> fileCnt )//... \ 0no: fname: size: mtime: {// If the selected file or folder is transmitted, the file information to be transmitted is generated. char buf [MAX_UDPBUF/2]; EncodeShareMsg (cmdinfo, buf, sizeof (buf); shareStr = new char [strlen (buf) + 1]; strcpy (shareS Tr, buf); shareMng-> AddHostShare (cmdinfo, sendEntry, sendEntryNum);} // The function for actually sending messages SendMsgSub (); return TRUE;} BOOL TSendDlg :: sendMsgSub (void) {BOOL makeNomalMsg = TRUE; for (int cnt = 0; cnt <sendEntryNum; cnt ++) {// if you need to obtain the encrypted key from the client to be sent, obtain the key if (sendEntry [cnt] first. status () = ST_GETCRYPT) {char spec_str [MAX_BUF]; int spec = IPMSG_RSA_512 | IPMSG_RC2_40; if (cfg-> pubKey. key () spec | = IPMSG_RSA_102 4 | IPMSG_BLOWFISH_128; wsprintf (spec_str, "% x", spec); msgMng-> Send (& sendEntry [cnt]. host ()-> hostSub, IPMSG_GETPUBKEY, spec_str);} // encrypt the data to be sent if (sendEntry [cnt]. status () = ST_MAKECRYPTMSG) {MakeEncryptPacket (sendEntry + cnt); // ST_MAKECRYPTMSG-> ST_SENDMSG} if (sendEntry [cnt]. status () = ST_MAKEMSG) {sendEntry [cnt]. setStatus (ST_SENDMSG); if (makeNomalMsg) msgMng-> MakeMsg (msgBuf, packetNo, Command &~ IPMSG_ENCRYPTOPT, msg. msgBuf, shareStr, & packetLen), makeNomalMsg = FALSE;} // After MakeEncryptPacket encrypts the message, set the host status to ST_SENDMSG if (sendEntry [cnt]. status () = ST_SENDMSG) {const char * str = sendEntry [cnt]. msg ()? SendEntry [cnt]. Msg (): msgBuf; int len = sendEntry [cnt]. Msg ()? SendEntry [cnt]. msgLen (): packetLen; // send data to the selected machine msgMng-> UdpSend (sendEntry [cnt]. host ()-> hostSub. addr, sendEntry [cnt]. host ()-> hostSub. portNo, str, len) ;}return TRUE ;}

The following is a packet that uses wireshark to capture and send messages using the Flying Pigeon mail.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.