Linux进程通讯之二:socket

2014-03-12 21:30:15

采用 udp socket,使用本机回环地址127.0.0.1进程间通讯。

1、头文件
#ifndef __MESSAGE_H__
#define __MESSAGE_H__
 
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
 
 
#define DEBUGMSG  0x01    //用于message out
 
 
#ifndef true
#define true  1
#endif
#ifndef false
#define false 0
#endif
 
#define HOST_IP_ADDR "127.0.0.1"
 
#define ID_SERVER_DVR               0x9960
 
#define ID_CLIENT_TR        0x9950
#define ID_CLIENT_X0        0x9940
#define ID_CLIENT_X1        0x8890
#define ID_CLIENT_X2        0x8880
#define ID_CLIENT_X3        0x8870
 
#define REQ_CONNECTREPEAT     3
#define REQ_DISCONNECTREPEAT  4
#define REQ_WRITEREPEAT       5
#define REQ_READREPEAT        6
#define ACK_MASK              0x8000
#define ACK_NO                0x8000
 
#define MSG_REBOOT            0x0001
#define MSG_FACTORY_RESET     0x0002
 
#define REPEATER_BUFF_SIZE 1024
 
//在以后用到的时候再具体定义            
typedef struct
{
    unsigned char data0;           
    unsigned long data1;       
    unsigned char data2;       
    unsigned char data3;   
    unsigned char data4;       
} IPCSOCKETPARATYPE;
 
 
typedef struct 
{
  int s;                   
  struct sockaddr_in sin;
  unsigned short myID;     
} MSGSOCKETTYPE; 
 
typedef struct
{
    unsigned short SourceID;    //源ID
    unsigned short DestID;      //目标ID
    unsigned short Operation;   //操作类型,0读/1写
    unsigned short Type;            //消息类型
    unsigned short Size;            //消息长度
} MESSAGEHEADTYPE;
 
//创建通道
int CreateChannel
(
  MSGSOCKETTYPE *pmsgSock,
  char *ip,                         //目标IP地址,如果是server端,添空NULL
  unsigned short ID         //端口号
);
 
//删除通道
int DeleteChannel
(
  MSGSOCKETTYPE *pmsgSock,
  unsigned short ID                
);
 
//发送消息
int sendmessage
(
  MSGSOCKETTYPE *pmsgSock,
  unsigned short ID,    //目的端口,如果是返回发送方填0
  void *Message,
  int Length
);
 
//接收消息
int recvmessage
(
  MSGSOCKETTYPE *pmsgSock,
  void *Buffer,
  int BufferSize,
  int Timeout
);
     
int rs_ConnectRepeaterService(char *ServerIP);
 
int rs_DisconnectRepeaterService(void);
 
int rs_RequstConnect(
    unsigned short myID,                                        //请求者
    unsigned short type,
    const IPCSOCKETPARATYPE *pUartCommAttr, //通讯数据
    int Timeout                                                         //超时时间,单位ms,未使用
);
 
int rs_RequstDisconnect(unsigned short myID,unsigned short type);
 
int rs_RequstWrite(
    unsigned short myID,
    unsigned short type,
    const unsigned char *Buffer,
    int Len
);
 
int rs_RequstRead(
    unsigned short myID,
    unsigned short type,
    unsigned char *Buffer,     
    int BufferSize,            
    int Timeout             //超时时间,单位ms
);
int rs_RequstCommute(int *connect,unsigned short type);
         
#endif
2​、server端
//ipc socket server
#include <stdlib.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <string.h>
#include <pthread.h>
 
#include "ipc_socket.h"
//#include "srvrepeatif.h"
 
unsigned long debug=0;
MSGSOCKETTYPE srvSock;
 
static IPCSOCKETPARATYPE CommPara;
 
void sig_ctrl_z(int z)
{
  DeleteChannel(&srvSock,ID_SERVER_DVR);
   
  printf("[srvrepeat]exit\r\n");
  exit(1);
}
 
int main(void)
{
  int rxlen=1;
   
  signal(SIGTSTP,sig_ctrl_z);
  signal(SIGTERM,sig_ctrl_z);
   
  printf("server:start\n");
  CreateChannel(&srvSock,NULL,ID_SERVER_DVR);
   
  while(1)
  {
    MESSAGEHEADTYPE *pMsgHead;
    unsigned char msg[1024];
    
    rxlen=recvmessage(&srvSock,msg,sizeof(msg),1000);
    if (rxlen<=0)
    {
        //没有请求
        continue;
    }
     
    //有请求到来
    if (rxlen<sizeof(MESSAGEHEADTYPE))
    {
     continue;
    }
     
    pMsgHead=(MESSAGEHEADTYPE *)msg;
    if ((pMsgHead->Size+sizeof(MESSAGEHEADTYPE))!=rxlen)
    {
      int i;
      {
        perror("server:recv msg size error:");
        for (i=0;i<rxlen;i++)
        {
          char buf[8];
          sprintf(buf,"%02X",msg[i]);
          perror(buf);
        }
        perror("\r\n");
      }
      continue;
    }
        printf("server:Operation->Type (0x%04x)\n",pMsgHead->Type);
     
    switch (pMsgHead->Operation)
    {
      case REQ_CONNECTREPEAT:
      {
        int Timeout;
        printf("server:Operation->REQ_CONNECTREPEAT, req connect\n");
        memcpy(&CommPara,msg+sizeof(MESSAGEHEADTYPE),sizeof(CommPara));
        memcpy(&Timeout,msg+sizeof(MESSAGEHEADTYPE)+sizeof(IPCSOCKETPARATYPE),sizeof(Timeout));
 
        if(1)   //success
        { 
            pMsgHead->Operation |= ACK_MASK;
            pMsgHead->Size=0;
             
            sendmessage(&srvSock,0,msg,sizeof(MESSAGEHEADTYPE));
 
            printf("server:Operation->REQ_CONNECTREPEAT success, sendmessage finish\n\n");
 
            break;
        }
        else
        {
            pMsgHead->Operation = ACK_NO;
            pMsgHead->Size=0;
            sendmessage(&srvSock,0,msg,sizeof(MESSAGEHEADTYPE));
            printf("server:Operation->REQ_CONNECTREPEAT failed, sendmessage finish\n\n");
        }
      }
      break;
 
      case REQ_DISCONNECTREPEAT:
      {
        printf("server:Operation->REQ_DISCONNECTREPEAT, req disconnect\n");
         
        pMsgHead->Operation |= ACK_MASK;
        pMsgHead->Size=0;
        sendmessage(&srvSock,0,msg,sizeof(MESSAGEHEADTYPE));
        printf("server:Operation->REQ_CONNECTREPEAT, sendmessage finish\n\n");
      }
      break;
         
      case REQ_WRITEREPEAT:
      {
                printf("server:Operation->REQ_WRITEREPEAT, req write\n"); 
                //printf("[srvrepeat]write:TxSize=%d\r\n",pMsgHead->Size);
        pMsgHead->Operation |= ACK_MASK;
        pMsgHead->Size=0;
        sendmessage(&srvSock,0,msg,sizeof(MESSAGEHEADTYPE));
        printf("server:Operation->REQ_WRITEREPEAT, sendmessage finish\n\n");
      }
      break;
         
      case REQ_READREPEAT:
      {
        int RxSize;
        int Timeout;
         
        printf("server:Operation->REQ_READREPEAT, req read\n");
        memcpy(&RxSize,msg+sizeof(MESSAGEHEADTYPE),sizeof(RxSize));
        memcpy(&Timeout,msg+sizeof(MESSAGEHEADTYPE)+sizeof(RxSize),sizeof(Timeout));
        if (RxSize>(sizeof(msg)-sizeof(MESSAGEHEADTYPE)-sizeof(RxSize)))//太大了,就弄小点
        {
            RxSize=sizeof(msg)-sizeof(MESSAGEHEADTYPE)-sizeof(RxSize);
        }
                printf("server:RxSize=%d,Timeout=%d\n",RxSize,Timeout);
 
        memcpy(msg+sizeof(MESSAGEHEADTYPE),&RxSize,sizeof(RxSize));
        pMsgHead->Operation |= ACK_MASK;
        pMsgHead->Size=sizeof(RxSize)+RxSize;
        sendmessage(&srvSock,0,msg,sizeof(MESSAGEHEADTYPE)+pMsgHead->Size);
        printf("server:Operation->REQ_READREPEAT, sendmessage finish\n\n");
         
      }
      break;
 
      default:
      {
                printf("server:Operation->default, req default\n");
        pMsgHead->Operation = ACK_NO;
        pMsgHead->Size=0;
        sendmessage(&srvSock,0,msg,sizeof(MESSAGEHEADTYPE));
      }
      break;
    } 
  }
     
  sig_ctrl_z(0);
  exit(1);
}
3、client端
//ipc socket client
#include <stdlib.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <string.h>
#include <pthread.h>
 
#include "ipc_socket.h"
//#include "srvrepeatif.h"
 
unsigned long debug=0;
 
static IPCSOCKETPARATYPE CommPara;
 
void sig_ctrl_z(int z)
{
  //DeleteChannel(&srvSock,ID_SERVER_DVR);
   
  printf("[srvrepeat]exit\r\n");
  exit(1);
}
 
int main(void)
{
  int rxlen=1;
   
  signal(SIGTSTP,sig_ctrl_z);
  signal(SIGTERM,sig_ctrl_z);
   
  IPCSOCKETPARATYPE IpcSocketAttr;
  unsigned char cmd_buff[REPEATER_BUFF_SIZE];
 
  if(rs_ConnectRepeaterService(HOST_IP_ADDR))
  {
 
  }
  while(1)
  { 
        IpcSocketAttr.data0 = 12;
        IpcSocketAttr.data1 = 34;
        IpcSocketAttr.data2 = 56;
        IpcSocketAttr.data3 = 78;
        IpcSocketAttr.data4 = 90;
     
        #define TIMEOUT_RECONNECT   10*1000
        if(!rs_RequstConnect(ID_CLIENT_TR,MSG_REBOOT,&IpcSocketAttr,    TIMEOUT_RECONNECT))
        {
            continue;
            return 0;
        }
         
        if(!rs_RequstWrite( ID_CLIENT_TR,MSG_REBOOT,cmd_buff, 7))
        {
            //continue;
            goto Exit_ERR;
        }
         
        memset(cmd_buff,0, REPEATER_BUFF_SIZE);
        if( rs_RequstRead(ID_CLIENT_TR,MSG_REBOOT,cmd_buff, REPEATER_BUFF_SIZE,1*1000) <= 0 )
        {
            //continue;
            goto Exit_ERR;
        }
         
        rs_RequstDisconnect(ID_CLIENT_TR,MSG_REBOOT);
        //continue;
         
        return 1;
           
        Exit_ERR:
         
        rs_RequstDisconnect(ID_CLIENT_TR,MSG_REBOOT);
        return 0;
     
  }
     
  sig_ctrl_z(0);
  exit(1);
}

 

4、其他 省略
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值