Windows网络编程基础(1)---邮槽

/*
2018-9-6 12:21:04
邮槽的使用
*/
预备知识:CreateFile,ReadFile的使用

关键的函数 CreateMailslot 如果建立失败 返回一个无效的句柄值INVILID_HANDLE_VALUE
用一个有效的句柄创建了邮槽之后,便可开始数据的实际读取。服务器是唯一能从邮槽
读入数据的进程
单项的 单线的数据传输


若想实现一个邮槽,要求开发一个服务器应用,来负责邮槽的创建。下述步骤解释了如
何编写一个基本的服务器应用:
1) 用CreateMailslot API函数创建一个邮槽句柄。
2) 调用ReadFile API函数,并使用现成的邮槽句柄,从任何客户端接收数据。
3) 用CloseHandle这个API函数,关闭邮槽句柄。
可以看出,要开发一个邮槽服务器程序,只需使用极少的 API调用。服务器进程是用
CreateMailslot这个API调用来创建邮槽的。定义如下
函数原型:

HANDLE CreateMailslot(
  LPCTSTR lpName,    //邮槽的名字
  DWORD nMaxMessageSize, //收到消息的长度设置,设置为0时表示可以接受任意长度的数据
  DWORD lReadTimeout,    //0 或者 MAILSLOT_WAIT_FOREVER    读取时间
  LPSECURITY_ATTRIBUTES lpSecurityAttributes     // inheritance option;
  }


服务端代码:
// MailSlot.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
 

#include <iostream>
#include <windows.h>
#include <string>

int main()
{
    //std::cout << "Hello World!\n"; 
    const TCHAR *lpszSlotName = L"\\\\.\\Mailslot\\sample_JamesWu9527mailslot";

    HANDLE mailslot = CreateMailslot(lpszSlotName, 0, MAILSLOT_WAIT_FOREVER, NULL);

    if (INVALID_HANDLE_VALUE == mailslot)
    {
        std::cout << "CreateMailSlot Error : " << GetLastError() << std::endl;
        return EXIT_FAILURE;
    }

    char strshowResult[256] = { 0 };
    DWORD Numberofbyteread;
    //发送数据
    while (0 != ReadFile(mailslot, strshowResult, 256, &Numberofbyteread, NULL))
    {
        std::cout <<"Service: =>"<< Numberofbyteread << "bytes >>" << strshowResult << std::endl;
        memcpy(strshowResult, "", Numberofbyteread);
        Numberofbyteread = 0;
    }

    system("pause");
    return EXIT_SUCCESS;
}


客户端
思想:
1) 使用CreateFile这个API函数,针对想向其传送数据的邮槽,打开指向它的一个引用句
柄。
2) 调用WriteFile这个API函数,向邮槽写入数据。
3) 完成了数据的写入后,用CloseHandle这个API函数,关闭打开的邮槽句柄。
Client1

#include <iostream>
#include <windows.h>
#include <string>

int main()
{
    wchar_t Servername[] = L"\\\\.\\Mailslot\\sample_JamesWu9527mailslot";
    HANDLE MailSlot = CreateFile(Servername, GENERIC_WRITE, FILE_SHARE_READ,
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    
    if (INVALID_HANDLE_VALUE == MailSlot)
    {
        std::cout << "Please start up the service...\n";
        std::cout << "Create File failed with Error Code: " << GetLastError() << std::endl;
        system("pause");
        return EXIT_FAILURE;
    }

    DWORD BytestWritten;
    std::string strInput;
    while (1)
    {
        std::cout << "Client1=>" << "Input you CMD: ";
        std::cin >> strInput;
        if ("exit" == strInput)
        {
            strInput = "The Client1 exited\n";
            BOOL bflag = WriteFile(MailSlot, strInput.c_str(), strInput.length(), &BytestWritten, NULL);
            if (FALSE == bflag)
            {
                std::cout << "Write file failed error " << GetLastError() << std::endl;
                system("pause");
                return EXIT_FAILURE;
            }
            break;
        }

        BOOL bflag = WriteFile(MailSlot, strInput.c_str(), strInput.length(), &BytestWritten, NULL);
        if (FALSE == bflag)
        {
            std::cout << "Write file failed error " << GetLastError() << std::endl;
            system("pause");
            return EXIT_FAILURE;
        }

        strInput = "";
    }

    std::cout << "Wrote " << BytestWritten << " bytes\n";
    CloseHandle(MailSlot);

    system("pause");
    return EXIT_SUCCESS;
}

服务端的一个升级版本

#include <iostream>
#include <windows.h>
#include <conio.h>

DWORD WINAPI ServerMialSlot(LPVOID lpPrameter);
void SendMessageToMainlSlot();
BOOL StopProcessing;

int main()
{
    StopProcessing = FALSE;
    DWORD ThreadId;
    HANDLE MailSlot = CreateThread(NULL, 0, ServerMialSlot, NULL, 0, &ThreadId);        //创建一个线程
    std::cout << "Press a key to stop the server\n";
    _getch();
    //getchar();

    StopProcessing = TRUE;
    SendMessageToMainlSlot();

    if (WaitForSingleObject(MailSlot, INFINITE) == WAIT_FAILED)
    {
        std::cout << "WaitForsingleobject failed with error " << GetLastError();
        return EXIT_FAILURE;
    }

    system("pause");
    return EXIT_SUCCESS;
}

DWORD __stdcall ServerMialSlot(LPVOID lpPrameter)
{
    HANDLE mailslot = CreateMailslot(L"\\\\.\\Mailslot\\sample_mailslot", 2048, MAILSLOT_WAIT_FOREVER, NULL);
    if (INVALID_HANDLE_VALUE == mailslot)
    {
        std::cout << "Failed to create a Mailslot the error code is: " << GetLastError();
        return EXIT_FAILURE;
    }

    char buffer[2048];
    DWORD numberofbyteRead;

    DWORD Ret = ReadFile(mailslot, buffer, 2048, &numberofbyteRead, NULL);
    while (Ret != 0)
    {
        if (StopProcessing)
            break;
        std::cout << "Received " << numberofbyteRead << " bytes\n";
    }

    CloseHandle(mailslot);

    return EXIT_SUCCESS;
}

void SendMessageToMainlSlot()
{
    HANDLE mailslot = CreateFile(L"\\\\.\\Mailslot\\sample_mailslot",
        GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == mailslot)
    {
        std::cout << "Create FIle failed with the error code: " << GetLastError();
        return;
    }

    DWORD byteswritten;
    if (0 == WriteFile(mailslot, "STOP", 4, &byteswritten, NULL))
    {
        std::cout << "WriteFile failed with error code: " << GetLastError();
        return;
    }

    CloseHandle(mailslot);
}


可以同上面的CLient进行测试

猜你喜欢

转载自blog.csdn.net/Wuzm_/article/details/82500976