#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <ntrip_util.h>
#include <cutils/properties.h>
char gpgga[] = "$GPGGA,083552.00,3000.0000000,N,11900.0000000,E,1,08,1.0,0.000,M,100.000,M,,*57\r\n";
int request_caster_success = 0;
int send_caster_request = 0;
int sock_fd = -1;
int status = 0;
char server_ip[PROPERTY_VALUE_MAX];
char server_port[PROPERTY_VALUE_MAX];
#define RECONNECT_INTERVAL 5
#define PROBE_INTERVAL 5
#define PROPERTY_NTRIPCASTER_USERNAME "persist.sys.ntrip_username"
#define PROPERTY_NTRIPCASTER_PASSWORD "persist.sys.ntrip_password"
#define PROPERTY_NTRIPCASTER_IP "persist.sys.ntrip_ip"
#define PROPERTY_NTRIPCASTER_PORT "persist.sys.ntrip_port"
#define PROPERTY_NTRIPCASTER_MOUNT_POINT "persist.sys.ntrip_point"
int open_tcp_client_socket_fd(char* serveraddr, char* rport){
int nvar;
short int nCloseConFlag = 0;
struct sockaddr_in stSrvAddr;
int nSendBuf = 32*1024;
int netmon_fd;
int iKeepAlive = 1;
struct timeval tv_out;
fd_set fdsWrite;
//printf("Connecting to server %s port %s \n",serveraddr, rport);
if((netmon_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
return -1;
}
//启用tcp协议自带的保活协议,效果比较差,因为为了防止keep-alive流量过大,系统设置的保活间隔很长很长
setsockopt(netmon_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&iKeepAlive, sizeof(iKeepAlive));
memset(&stSrvAddr, 0, sizeof(struct sockaddr_in));
stSrvAddr.sin_family = AF_INET;
stSrvAddr.sin_addr.s_addr = inet_addr(serveraddr);
stSrvAddr.sin_port = htons(atoi(rport));
/* 获取当前socket的属性, 并设置 noblocking 属性(connect noblock)*/
if((nvar = fcntl(netmon_fd,F_GETFL,0 )) < 0){
close(netmon_fd);
return -1;
}
nvar |= O_NONBLOCK;
if(fcntl(netmon_fd,F_SETFL,nvar) < 0){
close(netmon_fd);
return -1;
}
/*请求连接*/
nvar = connect(netmon_fd,(struct sockaddr*)&stSrvAddr ,sizeof(stSrvAddr));
if(nvar != 0){
/* it is in the connect process*/
if (EINPROGRESS == errno){
tv_out.tv_sec = 0;
tv_out.tv_usec = 300000;
FD_ZERO(&fdsWrite);
FD_SET(netmon_fd, &fdsWrite);
/*确定socket可读写数据*/
if(select(netmon_fd+1, NULL, &fdsWrite,NULL, &tv_out) > 0){
socklen_t nLen;
nLen = sizeof(nvar);
/*下面的一句一定要,主要针对防火墙*/
getsockopt(netmon_fd, SOL_SOCKET, SO_ERROR, &nvar, &nLen);
/*connect failed*/
if(nvar != 0){
nCloseConFlag = 1;
}
}else{
nCloseConFlag = 1;
}
}
/* #define EISCONN 106 : Transport endpoint is already connected */
else if(EISCONN != errno){
nCloseConFlag = 1;
}
if(nCloseConFlag){
printf("errno:%d\n", errno);
shutdown(netmon_fd, SHUT_RDWR);
close(netmon_fd);
netmon_fd = -1;
}
}
return netmon_fd;
}
int get_socket_link_status(void){
return status;
}
void set_socket_link_status(int sta){
if(sta == 0){
request_caster_success = 0;
send_caster_request = 0;
}
status = sta;
}
void *net_cable_disconnected_monitor(void *arg){
int ret;
while(1){
sleep(PROBE_INTERVAL);
//if socket not linked we don't do probe, because we are try to reconnected
if(get_socket_link_status()== 0){
continue;
}
//create a new socket. If failed, it indicate link is down, but we haven't received close handshake
ret = open_tcp_client_socket_fd(server_ip, server_port);
if(ret == -1){
set_socket_link_status(0);
}else{
close(ret);
}
}
return NULL;
}
void *connect_to_server_loop(void * arg){
int ret;
pthread_t tid;
pthread_create(&tid,NULL,net_cable_disconnected_monitor,NULL);
pthread_detach(tid);
time_t start, stop;
char recv_buf[1024] = {0};
RE_CONNECT:
do{
property_get(PROPERTY_NTRIPCASTER_IP,server_ip,"203.107.45.154");
property_get(PROPERTY_NTRIPCASTER_PORT,server_port,"8002");
sock_fd = open_tcp_client_socket_fd(server_ip,server_port);
if(sock_fd == -1){
sleep(RECONNECT_INTERVAL);
printf("connected error, sleep %d second try to reconnected!\n", RECONNECT_INTERVAL);
}else{
set_socket_link_status(1);
printf("connected success!\n");
}
}while(sock_fd == -1);
while(1){
memset(recv_buf,0,sizeof(recv_buf));
start = time(NULL);
ret = recv(sock_fd, (void *)recv_buf, sizeof(recv_buf), MSG_DONTWAIT);
stop = time(NULL);
if(ret == -1){
// socket nonblocking normal returned EAGAIN error
if(errno != EAGAIN){
printf("error occured, errno is %d/n", errno);
}
}else if(ret == 0){
set_socket_link_status(0);
printf("connectecd stream shutdown or received zero byte request!\n");
}else{
if((!strncmp(recv_buf, "ICY 200 OK\r\n", 12)) || (!strncmp(recv_buf, "200 OK\r\n", 8))){
request_caster_success = 1;
printf("recv data:[%d] used time:[%d]\n", ret, (int)(stop - start));
print_char(recv_buf, ret);
}else{
printf("recv data:[%d] used time:[%d]\n", ret, (int)(stop - start));
print_char_hex(recv_buf, ret);
}
}
if(get_socket_link_status() == 0){
printf("link down, try to reconnect!\n");
close(sock_fd);
goto RE_CONNECT;
}
//sleep(1);
}
return NULL;
}
int send_data(){
int ret_send;
char request_data[1024] = {0};
char userinfo_raw[48] = {0};
char userinfo[64] = {0};
char mountpoint[PROPERTY_VALUE_MAX];
char user[PROPERTY_VALUE_MAX];
char passwd[PROPERTY_VALUE_MAX];
property_get(PROPERTY_NTRIPCASTER_USERNAME,user,"qxubwe002");
property_get(PROPERTY_NTRIPCASTER_PASSWORD,passwd,"7704e1e");
property_get(PROPERTY_NTRIPCASTER_MOUNT_POINT,mountpoint,"AUTO");
snprintf(userinfo_raw, 63 , "%s:%s", user, passwd);
base64_encode(userinfo_raw, userinfo);
/* Generate request data format of ntrip. */
snprintf(request_data, 1023,
"GET /%s HTTP/1.0\r\n"
"User-Agent: %s\r\n"
"Accept: */*\r\n"
"Connection: close\r\n"
"Authorization: Basic %s\r\n"
"\r\n"
, mountpoint, client_agent, userinfo);
//link is down, we don't send data
if(get_socket_link_status() == 0){
//printf("not connceted to server, don't send data\n");
return -1;
}
if(!request_caster_success && !send_caster_request){
/* Send request data. */
send_caster_request = 1;
ret_send = send(sock_fd, request_data, strlen(request_data), 0);//发送数据
if(ret_send == -1){
printf("send caster request fail\n");
set_socket_link_status(0);
return -1;
}else{
printf("send caster request success\n");
}
}else{
ret_send = send(sock_fd, gpgga, strlen(gpgga), 0);
if(ret_send == -1){
printf("send gpgga data fail\n");
set_socket_link_status(0);
return -1;
}
printf("send gpgga data ok\n");
}
return ret_send;
}
int main(int argc, char *argv[]){
int ret;
pthread_t connect_thread;
ret = pthread_create(&connect_thread,NULL,connect_to_server_loop,NULL);
if(ret != 0){
printf("connect thread create failed!");
}
while(1){
ret = send_data();
if(ret

silencezhujianhua
- 粉丝: 17
最新资源
- 县城主干道排水工程施工组织设计.doc
- 浅议项目成本风险的管理.doc
- 大跨度框架梁高支模施工实例.doc
- 补偿收缩混凝土的设计技术.doc
- 070-消防局指定产品采购工作程序-(1).doc
- 地下室门式钢管脚手架施工方案2.doc
- 道路工程临时围挡施工方案.doc
- 现浇剪力墙结构地下室模板施工组织设计方案.doc
- 高强度螺栓的施工工艺.doc
- 程序接口设计6大原则.doc
- IE效率分析流程.doc
- 质量人升级的9大定律.docx
- 第七章-参数估计.doc
- 12玻璃幕墙的施工方案.doc
- 第二章工程经济(1).doc
- 新选择性必修三Unit1FacevaluesUnderstandingideas课件.ppt
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



- 1
- 2
- 3
- 4
- 5
- 6
前往页