linux socket, serial编程

描述网络地址的两个结构

struct sockaddr

{
unsigned short sa_family;
unsigned char sa_data[14];
}

strunct sockaddr_in
{
unsigned short int sin_family;// protocol family---AF_INET is usual
unsigned short int sin_port;  // net port
struct in_addr sin_addr; // net address
unsigned char sin_zero[8]; // unuse, full of zero
}
编程中大部分采用sockaddr_in而不使用sockaddr
struct in_addr
{
unsigned long int s_addr;
}


// net address convert (string to long int instance: "192.168.1.102" to int)
int inet_aton(const char *ptr,struct in_addr *add);
char *inet_ntoa(struct in_addr add);


// network byte sequence is big endian, if the cup is not match, should be convert
short int htons(short int value);
int htonl(int value);
short int ntohs(short int value);

int ntohl(int value);


PS: 本人常用的调试答应宏定义:

#ifdef DEBUG
#define PARAMETER_STRING __FILE__,__LINE__,__FUNCTION__
#define PARAMETER_FMT "%s,(%d),{%s}"
#define PRINT_DEBUG(fmt,...) do{\
printf(PARAMETER_FMT,PARAMETER_STRING);\
printf(fmt,##__VA_ARGS__);\
}while(0)
#else
#define PRINT_DEBUG(fmt,...)
#endif


linux tcp通信的流程如下图所示:


如下代码为linux环境下socket的tcp与udp模式,串口通信模式提供统一的接口,由_PORT_TYPE_e定义使用udp还是tcp,或者COM通信

头文件:

#ifndef __NET_H__
#define __NET_H__
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <arpa/inet.h>


#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <pthread.h>
#include <stdarg.h>
#include <termio.h>// uart driver
#include <stdlib.h>
#include <sys/stat.h> // file attribute
#include <fcntl.h>


typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned short uint16_t;
typedef short int16_t;
typedef unsigned char uint8_t;


#define DEBUG
#define MAX_PACKAGE 1500




#ifdef DEBUG
#define DEBUGARG __FILE__,__LINE__,__FUNCTION__
#define DEBUGFMT "%s(%d){%s}:"
#define PRINT_DEBUG(fmt,...) do{ \
printf(DEBUGFMT, DEBUGARG); \
printf(fmt, ##__VA_ARGS__); \
}while(0)

#define PRINT_MSG printf
#else
#define PRINT_DEBUG(fmt,...)  
#define PRINT_MSG(fmt,...) 
#endif




typedef  enum {COM1,COM2,COM3,ETHERNET1,ETHERNET2,ETHERNET3}_PORT_TYPE_e;


/*串口参数表*/
typedef struct {
uint32_t  baudrate; //波特率
uint32_t  datalen;   //数据位长度
uint32_t  stopbit;   //停止位
uint32_t  odd;     //奇偶校验位  0---无  1---奇校验  2---偶校验
}_UART_PARS_s;
_UART_PARS_s serial_conf;


typedef struct tty_info_t
{
    int fd;                 // 串口设备ID
    pthread_mutex_t mt;     // 线程同步互斥对象
    char name[24];         // 串口设备名称,例:"/dev/ttyS0"
    struct termios ntm;     // 新的串口设备选项
    struct termios otm;   // 旧的串口设备选项
} _TTY_INFO_s;




#ifdef DEBUG
#define FORMAT "{%s}-[%s]-(%d):"
#define PARMT __FILE__,__FUNCTION__,__LINE__
#define PRINT_DEBUG(fmt,...) do{ \
printf(FORMAT,PARMT); \
printf(fmt,##__VA_ARGS__); \
}while(0)
#define PRINT_MASG(fmt,...) printf(fmt,...)
#else
#define PRINT_MASG(fmt,...)
#define PRINT_DEBUG(fmt,...)

#endif */


typedef struct thread_para 
{
_PORT_TYPE_e port;
void (*receive)(_PORT_TYPE_e from,uint8_t *buf,uint32_t len,void* addr_info);
}_THREAD_PARA_s;

typedef struct {
uint8_t localIP[4]; //本地IP
uint32_t  localPort;   //本地端口
uint8_t netGate[4]; //网关IP
uint8_t netMask[4];   //子网掩码
uint8_t localDNS[4]; //DNS服务器IP

uint8_t  remoteIP[4];   //远程IP
uint32_t  remotePort; //远程端口
uint8_t protocolType; //使用UDP或TCP连接    0:UDP     1:TCP
}_ETHERNET_PARS_s;

_TTY_INFO_s *open_tty(uint32_t id);        //串口相关函数
int have_char_tty(_TTY_INFO_s *ptty);
int set_tty_speed(_TTY_INFO_s *ptty, uint32_t speed);
int set_tty_parity(_TTY_INFO_s *ptty,uint32_t databits,uint32_t parity,uint32_t stopbits);

int32_t CommInf_init_CommInf(_PORT_TYPE_e, void*,uint32_t,void(*)(_PORT_TYPE_e,uint8_t*,uint32_t,void*),void**);
int32_t  CommInf_send_data(_PORT_TYPE_e, uint8_t*, uint32_t,void* remote_info);
void  CommInf_close_CommInf (_PORT_TYPE_e);
int32_t CommInf_reconnect(uint32_t);


#endif


源文件:

#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <pthread.h>
#include <stdarg.h>
#include <termio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "netCommIfor.h"
//uint8_t  Flag_init=0;
/***************************UDP处理**************************************************/
struct Links_Objects *udp_link_head = NULL;
struct Links_Objects *udp_link_tail = NULL;
static unsigned int flag_shut_udp = 0;
static pthread_t udp_thread_id;
static int udp_max_fd = 0;
static int udp_fd_num;
static unsigned int udp_thread_running = 0;
static unsigned char udp_buf[MAX_PACKAGE];


/***************************TCP处理**************************************************/
struct Links_Objects *tcp_link_head = NULL;
struct Links_Objects *tcp_link_tail = NULL;
static unsigned int flag_shut_tcp = 0;
static pthread_t tcp_thread_id;
static int tcp_max_fd = 0;
static int tcp_fd_num;
static unsigned int tcp_thread_running = 0;
static unsigned char tcp_buf[MAX_PACKAGE];


/************************************************************************************/
static unsigned int flag_shut_uart = 0;
static pthread_t uart_thread_id;
_TTY_INFO_s *serial_info;
_ETHERNET_PARS_s *netParaLocal;
_THREAD_PARA_s serial_thread_para;


typedef void(*PFunc)(_PORT_TYPE_e ,uint8_t*,uint32_t,void*);


/*****************************************************************************************/
struct Objects_Opt{
int fd; //连接socket句柄
_PORT_TYPE_e port; //连接远程端口
PFunc deal; //连接处理函数
};


struct Links_Objects{
struct Objects_Opt opt;
struct Links_Objects *next;
};


int add_link(struct Objects_Opt* obj,int *maxfd,struct Links_Objects **start, struct Links_Objects **last)//添加一个连接
{
struct Links_Objects *obj_to_add;

obj_to_add = (struct Links_Objects*)malloc(sizeof(struct Links_Objects));
if(!obj_to_add) 
return 0;

memset(obj_to_add,0,sizeof(struct Links_Objects));

(obj_to_add->opt).fd = obj->fd;
(obj_to_add->opt).port = obj->port;
(obj_to_add->opt).deal = obj->deal;
obj_to_add->next = NULL;

if((obj->fd) > *maxfd)
*maxfd = obj->fd;

if (!*start) 
{
*start = obj_to_add;
*last = obj_to_add;
return 1;
}


(*last)->next = obj_to_add;
*last = obj_to_add;


return 1;
}


void del_link(int fd,struct Links_Objects **start, struct Links_Objects **last)//删除一个连接
{
struct Links_Objects *p = *start;
struct Links_Objects *p_prev = NULL;
for(;p != NULL;p = p->next)
{
if((p->opt).fd == fd)
{
if(p_prev)
p_prev->next = p->next;
else
*start = p->next;

if(!(p->next))
*last = p_prev;

free(p);
break;
}
p_prev = p;
}
}


int get_fd(_PORT_TYPE_e s_port,struct Links_Objects **start)//获取socket句柄
{
struct Links_Objects *p = *start;
for(;p != NULL;p = p->next)
{
if((p->opt).port == s_port)
{
return (p->opt).fd;
}
}
return 0;
}


int configure_read_set(fd_set* s_read_set,struct Links_Objects **start)//设置监控句柄
{
int read_fd_num = 0;
struct Links_Objects *p= *start;

FD_ZERO(s_read_set);

for(;NULL != p;p = p->next)
{
read_fd_num++;
FD_SET((p->opt).fd,s_read_set);
}

return read_fd_num;
}


_TTY_INFO_s *open_tty(_PORT_TYPE_e id)
{
static _TTY_INFO_s *ptty;


    ptty = (_TTY_INFO_s *)malloc(sizeof(_TTY_INFO_s));
    if(ptty == NULL)
    {
        return NULL;
    }


    memset(ptty,0,sizeof(_TTY_INFO_s));


    pthread_mutex_init(&ptty->mt,NULL);


    sprintf(ptty->name,"/dev/ttyS%d",id);


    ptty->fd = open(ptty->name, O_RDWR | O_NOCTTY |O_NDELAY);
    if (ptty->fd <0)
    {
        free(ptty);
        PRINT_MSG("open tty%d fail\n",id);
        return NULL;
    }


fcntl(ptty->fd, F_SETFL, 0);


    tcgetattr(ptty->fd,&ptty->otm); //取得并且保存原来的设置


    return ptty;
}


int set_tty_speed(_TTY_INFO_s *ptty, uint32_t baudrate)
{
    uint32_t speed;
    // 进行新的串口设置,数据位为8位
    if( tcgetattr(ptty->fd,&ptty->ntm) != 0)
    {
        PRINT_MSG("SetupSerial [%s] speed\n",ptty->name);
        return 1;
    }
    bzero(&ptty->ntm, sizeof(ptty->ntm));


    switch(baudrate)
    {
    case 300:
        speed= B300;
        break;
    case 1200:
        speed= B1200;
        break;
    case 2400:
        speed= B2400;
        break;
    case 4800:
        speed= B4800;
        break;
    case 9600:
        speed= B9600;
        break;
    case 19200:
        speed= B19200;
        break;
    case 38400:
        speed= B38400;
        break;
    case 115200:
        speed= B115200;
        break;
    }


cfsetispeed(&ptty->ntm, speed);
cfsetospeed(&ptty->ntm, speed);


//清除串口缓冲中的内容(对接收到而未被读取的数据进行清空处理)
    tcflush(ptty->fd, TCIFLUSH);
    tcsetattr(ptty->fd,TCSANOW,&ptty->ntm); //激活配置修改(立即生效)


    return 0;
}


int set_tty_parity(_TTY_INFO_s *ptty,uint32_t databits,uint32_t parity,uint32_t stopbits)
{
//取得新串口设置
    if( tcgetattr(ptty->fd,&ptty->ntm) != 0)
    {
        PRINT_MSG("SetupSerial [%s]\n",ptty->name);
        return 1;
    }






    ptty->ntm.c_cflag &= ~CSIZE; //设置数据位数
    switch (databits)
    {
    case 7:
        ptty->ntm.c_cflag |= CS7;
        break;
    case 8:
        ptty->ntm.c_cflag |= CS8;
        break;
    default:
        PRINT_MSG("Unsupported data size\n");
        return 5;
    }


    switch (parity)
    {                             //设置奇偶校验位数
    case 0:
        ptty->ntm.c_cflag &= ~PARENB; //不开启校验使能
        ptty->ntm.c_iflag &= ~INPCK; //不开启校验检查
        break;


    case 1:
        ptty->ntm.c_cflag |= (PARODD|PARENB); //设置为奇效验
        ptty->ntm.c_iflag |= INPCK; //开启校验检查
        break;


    case 2:
        ptty->ntm.c_cflag |= PARENB; //开启校验使能
        ptty->ntm.c_cflag &= ~PARODD; //转换为偶效验
        ptty->ntm.c_iflag |= INPCK; //当为偶校验的时候关闭奇校验
        break;


    default:
        PRINT_MSG("Unsupported parity\n");
        return 2;
    }


    // 设置停止位
    switch (stopbits)
    {
    case 1:
        ptty->ntm.c_cflag &= ~CSTOPB;
        break;
    case 2:
        ptty->ntm.c_cflag |= CSTOPB;
        break;
    default:
        PRINT_MSG("Unsupported stop bits\n");
        return 3;
    }


ptty->ntm.c_cflag |= (CLOCAL | CREAD); //不改变端口所有者,接收使能。
ptty->ntm.c_lflag &=~(ICANON | ECHO | ECHOE | ISIG); //设置为非规范模式
ptty->ntm.c_oflag &=~OPOST; //不启用输出处理功能
ptty->ntm.c_iflag &=~(IXON | ICRNL); //不处理控制字符


    ptty->ntm.c_cc[VTIME] =0;   //不等待,立即返回
    ptty->ntm.c_cc[VMIN] = 1;   //只要有一个数据就读取
    tcflush(ptty->fd, TCIFLUSH);
    if (tcsetattr(ptty->fd,TCSANOW,&ptty->ntm) != 0) //使上面的设置立即生效
    {
        PRINT_MSG("SetupSerial \n");
        return 4;
    }


    return 0;
}


int create_udp_socket(char *ip,unsigned short port)
{
int fd;
struct sockaddr_in m_udpsocket_addr;
memset(&m_udpsocket_addr,0,sizeof(m_udpsocket_addr));


m_udpsocket_addr.sin_family = PF_INET;
if(ip != NULL)
{
m_udpsocket_addr.sin_addr.s_addr = inet_addr(ip);
}
else
{
m_udpsocket_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
}
m_udpsocket_addr.sin_port = htons(port);
fd = socket(PF_INET,SOCK_DGRAM,0);


if(-1 == fd )
{
PRINT_MSG("create udp socket failed,errno = %d\n",errno);
return -1;
}
if(-1 == bind(fd, (struct sockaddr *)&m_udpsocket_addr, sizeof(struct sockaddr)))
{
PRINT_MSG("bind socket fialed,errno = %d\n",errno);
close(fd);
return -1;
}
return fd;
}


int create_tcp_socket(char *ip,unsigned short port)
{
int fd;
struct sockaddr_in m_tcpsocket_addr;


memset(&m_tcpsocket_addr,0,sizeof(m_tcpsocket_addr));


m_tcpsocket_addr.sin_family = PF_INET;
if(ip != NULL)
{
m_tcpsocket_addr.sin_addr.s_addr = inet_addr(ip);
}
else
{
m_tcpsocket_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
}
m_tcpsocket_addr.sin_port = htons(port);
fd = socket(PF_INET,SOCK_STREAM,0);


if(-1 == fd)
{
PRINT_MSG("create tcp socket failed,errno = %d\n",errno);
return -1;
}


if(-1 == connect(fd, (struct sockaddr *)&m_tcpsocket_addr, sizeof(struct sockaddr)))
{
PRINT_MSG("connect socket fialed,errno = %d,\n",errno);
close(fd);
return -1;
}


return fd;
}


void *uart_recv_deal(void *para)
{
struct timeval sel_time;
fd_set readfd;
uint32_t ret_sel,ret_read,max,return_read=0;
char *pbuf;
max=serial_info->fd+1;


_THREAD_PARA_s *p=(_THREAD_PARA_s *)para;
PRINT_MSG("read thread is begain:\n");


while(!flag_shut_uart)
{
FD_ZERO(&readfd);
FD_SET(serial_info->fd,&readfd);
sel_time.tv_sec=1;
sel_time.tv_usec=0;       //阻塞的时间为1s
ret_sel=select(max,&readfd,NULL,NULL,&sel_time);


if(ret_sel==0)
{
PRINT_MSG("serial thread wait over:\n");
}
else if(FD_ISSET(serial_info->fd,&readfd)>0)
{
pthread_mutex_lock(&serial_info->mt);


ioctl(serial_info->fd, FIONREAD, &ret_read);
PRINT_MSG("ttyS have %d data.\n",ret_read);


if(!ret_read)
{
fprintf(stderr, "Communication closed by server\n");
pthread_exit(0);
}
return_read = read(serial_info->fd,pbuf,ret_read);


if(ret_read >0)
{
p->receive(p->port,(uint8_t*)pbuf,ret_read,NULL);
}
else
{
PRINT_MSG("read serial data error.\n");
}
pthread_mutex_unlock(&serial_info->mt);
}
ret_read=0;
return_read=0;
}
PRINT_MSG("uart read thread is end:\n");
pthread_exit (NULL);
}


void *udp_recv_deal (void *arg)
{
struct timeval net_timeval;
fd_set net_fds;
int ret;
struct sockaddr_in m_addr;
socklen_t m_addr_length = sizeof(m_addr);
udp_thread_running = 1;
    while (!flag_shut_udp)
    {
udp_fd_num = configure_read_set(&net_fds,&udp_link_head);
net_timeval.tv_sec   =  0 ;
net_timeval.tv_usec   =   30000;
ret = select(udp_max_fd +1,&net_fds,NULL,NULL,&net_timeval);
if(-1 == ret)
{
PRINT_MSG("socket receive thread fialed\n");
sleep(1);
udp_thread_running = 0;
pthread_exit (NULL);
}
else
{
if(ret > 0)
{
struct Links_Objects *p = udp_link_head;
for(;NULL != p;p = p->next)
{
if(FD_ISSET((p->opt).fd,&net_fds))
{
int reval;
reval = recvfrom((p->opt).fd,udp_buf,MAX_PACKAGE,0,(struct sockaddr*)&m_addr,&m_addr_length);
if(-1 == reval)
{
PRINT_MSG("recvfrom failed,errno = %d\n",errno);
sleep(1);
udp_thread_running = 0;
pthread_exit (NULL);
}
if(0 < reval)
{
memset(&udp_buf[reval],0,MAX_PACKAGE-reval);
PRINT_MSG("Receive from[IP:%s Port:%d]\n",inet_ntoa(m_addr.sin_addr),ntohs(m_addr.sin_port));
if(NULL != (p->opt).deal)
{
(p->opt).deal(ETHERNET1,udp_buf,reval,(void*)&m_addr);
}
}
ret--;
}
if(0 == ret)
{
break;
}
}
}
}
}
PRINT_MSG("udp read thread is end:\n");
udp_thread_running = 0;
    pthread_exit (NULL);
}


void *tcp_recv_deal (void *arg)
{
struct timeval tcp_timeval;
fd_set net_fds;
int ret;
tcp_thread_running = 1;
    while (!flag_shut_tcp)
    {
tcp_fd_num = configure_read_set(&net_fds,&tcp_link_head);
tcp_timeval.tv_sec   =  0 ;
tcp_timeval.tv_usec   =   100000;
ret = select(tcp_max_fd +1,&net_fds,NULL,NULL,&tcp_timeval);
if(-1 == ret)
{
PRINT_MSG("socket receive thread fialed\n");
sleep(1);
tcp_thread_running = 0;
pthread_exit(NULL);
}
else if(0 < ret)
{
struct Links_Objects *p = tcp_link_head;
for(;NULL != p;p = p->next)
{
if(FD_ISSET((p->opt).fd,&net_fds))
{
int reval;
reval = recv((p->opt).fd,tcp_buf,MAX_PACKAGE,0);
if(-1 == reval)
{
sleep(1);
tcp_thread_running = 0;
pthread_exit (NULL);
}
if(0 < reval)
{
memset(&tcp_buf[reval],0,MAX_PACKAGE-reval);
if(NULL != (p->opt).deal)
{
(p->opt).deal((p->opt).port,tcp_buf,reval,NULL);
}
}

ret--;
}

if(0 == ret)
{
break;
}
}
}
else if(0 == ret)
{
//recv(tcpReadfd,tcp_buf,MAX_PACKAGE,0); //用recv测试网络是否断开,如果断开会发送SIGPIPE给进程
//PRINT_MSG("checking net\n");
}
}
    PRINT_MSG("tcp read thread is end:\n");
tcp_thread_running = 0;
    pthread_exit(NULL);
}


int32_t CommInf_init_CommInf(_PORT_TYPE_e num, void* parsStruct,uint32_t len,PFunc func,void** pthread_id)
{


char ip[]="255.255.255.255";
switch(num)
{
case ETHERNET1:
case ETHERNET2:
case ETHERNET3:
{
struct Objects_Opt obj;
obj.port = num;
obj.deal = func;
netParaLocal = (_ETHERNET_PARS_s*)parsStruct;
if(!netParaLocal->protocolType)   //udp模式
{
snprintf(ip, sizeof(ip), "%d.%d.%d.%d",netParaLocal->localIP[0], netParaLocal->localIP[1], netParaLocal->localIP[2], netParaLocal->localIP[3]);
PRINT_MSG("%s\n",ip);


obj.fd = create_udp_socket(ip,netParaLocal->localPort);//是否允许同一个端口被多次绑定????


if(-1 == obj.fd)
{
PRINT_MSG("init CommInf failed\n");
return -1;
}

if(!add_link(&obj,&udp_max_fd,&udp_link_head,&udp_link_tail))
{
close(obj.fd);
PRINT_MSG("add_link occure an error\n"); 
return -1;
}

if(!udp_thread_running)//线程未运行?
{
if(pthread_create(&udp_thread_id,NULL,udp_recv_deal,NULL)!=0)
{
del_link(obj.fd,&udp_link_head,&udp_link_tail);
close(obj.fd);
PRINT_MSG("UserTimer thread (create) error\n");
return -1;
}
PRINT_MSG("udp_thread_id=%u\n",(uint32_t)udp_thread_id);
if(pthread_id)
*pthread_id = (void*)&udp_thread_id;
}
}
else //tcp模式
{
snprintf(ip, sizeof(ip), "%d.%d.%d.%d",netParaLocal-> remoteIP[0],netParaLocal->remoteIP[1],netParaLocal->remoteIP[2],netParaLocal->remoteIP[3]);
PRINT_MSG("%s\n",ip);
obj.fd =  create_tcp_socket(ip,netParaLocal->remotePort);

if(-1 == obj.fd)
{
PRINT_MSG("init CommInf tcp failed\n");
return -1;
}

if(!add_link(&obj,&tcp_max_fd,&tcp_link_head,&tcp_link_tail))
{
close(obj.fd);
PRINT_MSG("add_link occure an error\n");
return -1;
}


if(!tcp_thread_running)//线程未运行?
{
if(pthread_create(&tcp_thread_id,NULL,tcp_recv_deal,NULL) !=0 )
{
del_link(obj.fd,&udp_link_head,&udp_link_tail);
close(obj.fd);
PRINT_MSG("UserTimer thread (create) error\n");
return -1;
}

if(pthread_id)
*pthread_id = (void*)&tcp_thread_id;
}
}
break;
}
case COM1:
case COM2:
case COM3:
{
int32_t ret;
serial_thread_para.port = num;
serial_thread_para.receive = func;
//设置串口。
serial_info=open_tty(num);

serial_conf=*(_UART_PARS_s*)parsStruct;


set_tty_speed(serial_info, serial_conf.baudrate);


if((ret=set_tty_parity(serial_info,serial_conf.datalen,
serial_conf.odd,serial_conf.stopbit))==0)
{
pthread_create(&uart_thread_id,NULL,uart_recv_deal,
&serial_thread_para);
if(pthread_id)
*pthread_id = (void*)&uart_thread_id;
}
else
{
PRINT_MSG("set_tty_parity error\n");
}
break;
}


default:
break;
}
return 0;
}


int32_t  CommInf_send_data(_PORT_TYPE_e from, uint8_t  *buf,  uint32_t  len,void* remote_info)
{
uint32_t ret=0;


switch(from)
{
case ETHERNET1:
case ETHERNET2:
case ETHERNET3:
{
if(!netParaLocal->protocolType)   //udp模式
{
int udpReadfd = get_fd(from,&udp_link_head);
struct sockaddr_in m_addr;
if(!remote_info)
{
memset(&m_addr,0,sizeof(m_addr));
m_addr.sin_family = PF_INET;
char ip[]="255.255.255.255";
snprintf(ip, sizeof(ip), "%d.%d.%d.%d",netParaLocal-> remoteIP[0],netParaLocal-> remoteIP[1],netParaLocal-> remoteIP[2],netParaLocal-> remoteIP[3]);
m_addr.sin_addr.s_addr = inet_addr(ip);
m_addr.sin_port = htons(netParaLocal->remotePort);
PRINT_MSG("UDP mode Send to <IP:%s PORT:%d>\n",ip,netParaLocal->remotePort);
ret = sendto(udpReadfd,buf,len,0,(struct sockaddr*)&m_addr,sizeof(struct sockaddr));
if(-1 == ret)
{
PRINT_MSG("socket send data error = %d\n",ret);
return -1;
}
}
else
{
m_addr = *(struct sockaddr_in*)remote_info;
ret = sendto(udpReadfd,buf,len,0,(struct sockaddr*)&m_addr,sizeof(struct sockaddr));
}
}
else //tcp
{
int tcpReadfd = get_fd(from,&tcp_link_head);


ret = send(tcpReadfd,buf,len,0);


if(-1 == ret)
{
PRINT_MSG("socket send data error = %d\n",ret);
return -1;
}
}
break;
}


case COM1:
case COM2:
case COM3:
{
pthread_mutex_lock(&serial_info->mt);


ret=write(serial_info->fd,buf,len);


if(ret!=len)
{
PRINT_MSG("write serial error\n");
}
else if(-1 == ret)
{
PRINT_MSG("socket send data error = %d\n",ret);
return -1;
}


pthread_mutex_unlock(&serial_info->mt);
break;
}


default:
{
PRINT_MSG("PORT_TYPE error");
break;
}
}
return ret;
}


int32_t CommInf_reconnect(uint32_t num)
{
struct sockaddr_in m_tcpsocket_addr;


char ip[]="255.255.255.255";
snprintf(ip, sizeof(ip), "%d.%d.%d.%d",netParaLocal-> remoteIP[0],netParaLocal-> remoteIP[1],netParaLocal-> remoteIP[2],netParaLocal-> remoteIP[3]);




memset(&m_tcpsocket_addr,0,sizeof(m_tcpsocket_addr));


m_tcpsocket_addr.sin_family = PF_INET;
m_tcpsocket_addr.sin_addr.s_addr = inet_addr(ip);
m_tcpsocket_addr.sin_port = htons(netParaLocal->remotePort);


int tcpReadfd = socket(PF_INET,SOCK_STREAM,0);


if(-1 == tcpReadfd )
{
PRINT_MSG("create tcp socket failed,errno = %d\n",errno);
return 0;
}


while((-1 == connect(tcpReadfd, (struct sockaddr *)&m_tcpsocket_addr, sizeof(struct sockaddr)))
&&(num--))
{
PRINT_MSG("connect socket fialed! try again times=%d\n",num);
sleep(1);
}
if(!tcp_thread_running)
{
if(pthread_create(&tcp_thread_id,NULL,tcp_recv_deal,NULL)!=0)
{
PRINT_MSG("UserTimer thread (create) error\n");
return 0;
}
}
return 1;
}


void  CommInf_close_CommInf (_PORT_TYPE_e  port)
{
switch(port)
{
case ETHERNET1:
case ETHERNET2:
case ETHERNET3:
{
if(netParaLocal->protocolType)   //tcp模式
{
int fd = get_fd(port,&tcp_link_head);
del_link(fd,&tcp_link_head,&tcp_link_tail);
close(fd);
if(port == ETHERNET1)
PRINT_MSG("close ETHERNET1 CommInf tcp OK\n");
else if(port == ETHERNET2)
PRINT_MSG("close ETHERNET2 CommInf tcp OK\n");
else if(port == ETHERNET3)
PRINT_MSG("close ETHERNET3 CommInf tcp OK\n");
if(tcp_fd_num)//当没有socket时,终止线程!!!
{
if(!flag_shut_tcp)
{
flag_shut_tcp = 1;
pthread_join (tcp_thread_id, NULL);
}
}
}
else
{
int fd = get_fd(port,&udp_link_head);
del_link(fd,&udp_link_head,&udp_link_tail);
close(fd);

if(port == ETHERNET1)
PRINT_MSG("close ETHERNET1 CommInf tcp OK\n");
else if(port == ETHERNET2)
PRINT_MSG("close ETHERNET2 CommInf tcp OK\n");
else if(port == ETHERNET3)
PRINT_MSG("close ETHERNET3 CommInf tcp OK\n");

if(udp_fd_num)//当没有socket时,终止线程!!!
{
if(!flag_shut_udp)
{
flag_shut_udp = 1;
pthread_join (udp_thread_id, NULL);
}
}
}
break;
}


case COM1:
case COM2:
case COM3:
{
if(!flag_shut_uart)
{
flag_shut_uart = 1;
pthread_join (uart_thread_id, NULL);
if(serial_info->fd>0)
{
tcsetattr(serial_info->fd,TCSANOW,&serial_info->otm);
if(close(serial_info->fd))
{
PRINT_MSG("close CommInf uart OK\n");
}
serial_info->fd = -1;
free(serial_info);
serial_info = NULL;
}
}
break;
}


default:
{
PRINT_MSG("PORT_TYPE error");
break;
}
}
}


以此为初学者提供参考,希望对大家有所帮助。如果不正确之处请指教。





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值