描述网络地址的两个结构
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;
}
}
}
以此为初学者提供参考,希望对大家有所帮助。如果不正确之处请指教。