进程通信 命名管道与SOCKET

命名管道的好处是使用方便传送快。但是也有坏处,就是不同的用户之间是无法进行通信的。所谓不同用户就是在WINDOWS中的进程所属用户不同。

先留一个命名管道的通信的例子:
ContractedBlock.gif ExpandedBlockStart.gif 客户端 - 写入
    HANDLE hPipe = CreateFile("\\\\.\\Pipe\\NamedPipe", GENERIC_READ | GENERIC_WRITE, \
        
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL) ;
    
if ( hPipe == INVALID_HANDLE_VALUE )
    {
        
return ;
    }
    
    DWORD  nWriteByte ;
    
char buf='1';

    WriteFile( hPipe, 
&buf, sizeof(buf), &nWriteByte, NULL ) ;

    CloseHandle ( hPipe ) ;

ContractedBlock.gif ExpandedBlockStart.gif 服务端 - 接收
struct Pipeinfo
{
    HANDLE hPipe;
    HANDLE hEvent;
    HANDLE hTread;
    
};

//创建接收线程
void createInstance()
{
CString lpPipeName 
= "\\\\.\\Pipe\\NamedPipe" ;

// 创建管道实例
CurPipeInst.hPipe =  CreateNamedPipe ( lpPipeName, PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, \
PIPE_TYPE_BYTE
|PIPE_READMODE_BYTE|PIPE_WAIT, 1001000, NULL ) ;
if ( CurPipeInst.hPipe == INVALID_HANDLE_VALUE )
{
    DWORD dwErrorCode 
= GetLastError () ;
    
return ;
}
// 为每个管道实例创建一个事件对象,用于实现重叠IO
CurPipeInst.hEvent  =  CreateEvent ( NULL, falsefalsefalse ) ;
// 为每个管道实例分配一个线程,用于响应客户端的请求
CurPipeInst.hTread = AfxBeginThread ( ServerThread, &CurPipeInst, THREAD_PRIORITY_NORMAL ) ;
}


//线程服务函数
UINT ServerThread ( LPVOID lpParameter )
{
    DWORD  nReadByte 
= 0, nWriteByte = 0, dwByte = 0 ;  
    
char  szBuf ='0' ;
    Pipeinfo  CurPipeInst 
= *(Pipeinfo*)lpParameter ;
    OVERLAPPED OverLapStruct 
= { 0000, CurPipeInst.hEvent } ;
    
while ( true )
    {
        
// 命名管道的连接函数,等待客户端的连接(只针对NT)
        ConnectNamedPipe ( CurPipeInst.hPipe, &OverLapStruct ) ;
        
// 实现重叠I/0,等待OVERLAPPED结构的事件对象
        WaitForSingleObject ( CurPipeInst.hEvent, INFINITE ) ;
        
// 检测I/0是否已经完成,如果未完成,意味着该事件对象是人工设置,即服务需要停止
        if ( !GetOverlappedResult ( CurPipeInst.hPipe, &OverLapStruct, &dwByte, true ) )
            
break ;
        
        
// 从管道中读取客户端的请求信息
        if ( !ReadFile(CurPipeInst.hPipe, &szBuf, sizeof(szBuf), &nReadByte, NULL ) )
        {
            
//读取错误
            break ;
        }

        
if(szBuf=='1')
        {
            
//收到消息
            return 1;
        }
        
// 断开客户端的连接,以便等待下一客户的到来
        DisconnectNamedPipe ( CurPipeInst.hPipe ) ;
    }
    
return 0 ;
}

为了达到不同用户之间进行通信,可以采用SOCKET的方式,同样放上例子:
首先是都要放的声明:
#include <winsock.h>
#pragma comment(lib, "ws2_32.lib")
然后:
ContractedBlock.gif ExpandedBlockStart.gif 客户端
#define SERVER_ADDRESS "127.0.0.1"
#define PORT           9876
#define MSGSIZE        1024

SOCKET      sClient;
SOCKADDR_IN server;

void test()
{
    WSADATA     wsaData;
    WSAStartup(
0x0202&wsaData);
    
// Create client socket
    sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
// Connect to server
    memset(&server, 0sizeof(SOCKADDR_IN));
    server.sin_family 
= AF_INET;
    server.sin_addr.S_un.S_addr 
= inet_addr(SERVER_ADDRESS);
    server.sin_port 
= htons(PORT);
    connect(sClient, (
struct sockaddr *)&server, sizeof(SOCKADDR_IN));

    
char  szMessage[MSGSIZE];

    szMessage[
0]='1';
    send(sClient, szMessage, strlen(szMessage), 
0);

    closesocket(sClient);
    WSACleanup();
}

ContractedBlock.gif ExpandedBlockStart.gif 服务端代码
SOCKET g_CliSocketArr ;
//开始运行进程
void startSocket()
{

    
if(g_CliSocketArr)
    {
        closesocket(g_CliSocketArr);
    }
    WSADATA     wsaData;
    SOCKET      sListen, sClient;
    SOCKADDR_IN local, client;
    
int         iaddrSize = sizeof(SOCKADDR_IN);
    DWORD       dwThreadId;
    
// Initialize Windows socket library
    WSAStartup(0x0202&wsaData);
    
// Create listening socket
    sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
if (sListen == INVALID_SOCKET) {
        MessageBox(
"error");        
    }
    
// Bind
    local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    local.sin_family 
= AF_INET;
    local.sin_port 
= htons(PORT);
    bind(sListen, (
struct sockaddr *)&local, sizeof(SOCKADDR_IN));
    
// Listen
    listen(sListen, 3);
    
// Accept a connection
    sClient = accept(sListen, (struct sockaddr *)&client, &iaddrSize);
    
// Add socket to g_CliSocketArr
    g_CliSocketArr = sClient;
    CreateThread(NULL, 
0, WorkerThread, NULL, 0&dwThreadId);  

    
return ;

}
//接收消息进程
DWORD WINAPI WorkerThread(LPVOID lpParam)
{
    
int ret;
    
char szMessage[1024];
    
while(1)
    {
        
if(g_CliSocketArr!=NULL)
        {
            ret 
= recv(g_CliSocketArr, szMessage, MSGSIZE, 0);
            
if (ret == SOCKET_ERROR || g_mannuloff)
            {
                
// Client socket closed
                closesocket(g_CliSocketArr);
                g_CliSocketArr
=NULL;
                
return 1;
            }
            
else
            {
                ofstream outfile(
"D:\\ioinfo.txt",ofstream::out|ofstream::app);
                SYSTEMTIME sys;
                GetLocalTime( 
&sys ); 
                outfile
<<"Message:"<<szMessage<<"  Time:"<<sys.wHour<<":"<<sys.wMinute<<":"<<sys.wSecond;
                outfile
<<"\r\n";
            }
            
        }        
    }
    
return 0;
}

此文主要是为了自己方便所以没有太多的解释,而且都是单向通信非双向。

转载于:https://www.cnblogs.com/oplusx/archive/2009/08/30/1556901.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值