socket

Posted zhangerxiaoma

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了socket相关的知识,希望对你有一定的参考价值。

#include"public.h"
#include <error.h>
#include <pthread.h>
#define PORT 5990
#define MAXDATASIZE 100

void Analysis_VACP(const char *buf, char *send_buf, int *sendlen);
void jiexi();


int client_init(int portnum, char *hostname)
{
int sockfd = 0;
struct sockaddr_in server_addr;
struct hostent *host;

host = (struct hostent *)gethostbyname(hostname);
if(host == NULL)
{
perror("gethostbyname");
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd <= 0){
perror("socket");
}else{
/* 客户程序填充服务端的资料 */
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(portnum);
server_addr.sin_addr = *((struct in_addr *) host->h_addr);
//printf("IP:%s\n",from_ip);

if (connect(sockfd, (struct sockaddr *) (&server_addr), sizeof(struct sockaddr)) < 0)
{
close(sockfd);
}else;

}
return sockfd;
}

/***************************************************
*
* write to file fd
*
***************************************************/
int my_write(int fd, const char *buf, const int buf_len)
{
int size = 0;
int pos = 0;
int ret = 0;
int loop = 5;
size = buf_len;
while(size > 0){
ret = write(fd, buf + pos, size);
if(ret < 0){
loop--;
if(errno == EINTR){
continue;
}else;
}else{
size -= ret;
pos += ret;
}
if(loop < 0){
break;
}else;
}
return loop;
}
/*
1、经度 2、纬度 3、南半球 4、北半球 5、GPS是否定位 6、当前天线状态

*/
//得到数据函数,共享内存还是文件形式

void Analysis_VACP(const char *buf, char *send_buf, int *sendlen)
{
int ant_status = 0; //天线当前状态
int GPSLocate = 0; //判断是否GPS定位 0定位,1未定位
int North_flag = 0; //南北半球 0:北半球 1:南半球
int South_flag = 0; //东西半球 0:东半球 1:西半球
int longtitude = 0; //经度
int latitude = 0; //纬度
//解析buf协议,及对应发送send_buf相关协议
int send_len=0;
UNION_U tmp_data;

send_buf[send_len++] = 0xde;
send_buf[send_len++] = 0xad;
send_buf[send_len++] = 0xbe;
send_buf[send_len++] = 0xef;
send_buf[send_len++] = 0x00;//有效长度
send_len = 6;
switch(buf[6])
{
case 0x06://vsat给ACU配置信息


break;
case 0x08:
printf("0x08\n");


float agc;//当前天线的信号强度
float power_val;//当前天线功率

agc =0;
power_val=0;
//发送0x09
send_buf[send_len++] = 0x09;//协议命令
send_buf[send_len++] = 0x02;
send_buf[send_len++] = 0x04;//0xff;//ACU ID
send_buf[send_len++] = buf[9];
send_buf[send_len++] = 0x01;
//最后一次接收到的VACP发来的Seq_num
send_buf[send_len++] = buf[11];
send_buf[send_len++] = buf[12];
send_buf[send_len++] = buf[13];
send_buf[send_len++] = buf[14];
//
send_buf[send_len++] = 0x00;
send_buf[send_len++] = 0x00;
send_buf[send_len++] = 0x00;//最后一位可变,暂时不确定
//如果找到目标,进行跟踪,则Status_locked1=1
//xxxxx101
//此处需要得到天线状态
ant_status = 0;//默认初始化

if(ant_status == 0)//初始化 00001101
{
send_buf[send_len++] = 0x0d;
}else if(ant_status == 0)//展开00010101
{
send_buf[send_len++] = 0x15;
}else if(ant_status == 0)//搜索00100101
{
send_buf[send_len++] = 0x25;
}else if(ant_status == 0)//跟踪01000101
{
send_buf[send_len++] = 0x45;
}else if(ant_status == 0)//锁定10000101
{
send_buf[send_len++] = 0x85;
}
//故障代码
/*
send_buf[send_len++] = 0xff;
send_buf[send_len++] = 0xff;
send_buf[send_len++] = 0xfc;
send_buf[send_len++] = 0x19;
*/
//故障长度
send_buf[send_len++] = 0x0;
//发送信号
tmp_data.u__i = agc*10;

send_buf[send_len++] = (tmp_data.s.s3 &0xff);
send_buf[send_len++] = (tmp_data.s.s2 &0xff);
send_buf[send_len++] = (tmp_data.s.s1 &0xff);
send_buf[send_len++] = (tmp_data.s.s0 &0xff);
//config_id
send_buf[send_len++] = buf[10];

tmp_data.u__i = power_val*10;
send_buf[send_len++] = (tmp_data.s.s3 &0xff);
send_buf[send_len++] = (tmp_data.s.s2 &0xff);
send_buf[send_len++] = (tmp_data.s.s1 &0xff);
send_buf[send_len++] = (tmp_data.s.s0 &0xff);



break;
case 0x09:
printf("0x09\n");
break;
case 0x0a: //10
printf("0x0a\n");
break;
case 0x0b: //11 得到VSAT状态信息
printf("0x0b\n");
//acu返回协议0x0f
send_buf[send_len++] = 0x0f;//协议命令
send_buf[send_len++] = 0x02;
send_buf[send_len++] = 0xff;//ACU ID
send_buf[send_len++] = buf[9];
send_buf[send_len++] = 0x01;
send_buf[send_len++] = 0x0b;

break;

case 0x0c: //12 查询地理位置
printf("0x0c\n");

//发送0x07地理位置给VSAT
//send_buf[send_len++] = 0x21;
send_buf[send_len++] = 0x07;//协议命令
send_buf[send_len++] = 0x02;
send_buf[send_len++] = buf[8];//ACU ID
send_buf[send_len++] = buf[9];
send_buf[send_len++] = 0x01;
//最后一次接收到的VACP发来的Seq_num
send_buf[send_len++] = buf[11];
send_buf[send_len++] = buf[12];
send_buf[send_len++] = buf[13];
send_buf[send_len++] = buf[14];

send_buf[send_len++] = 0x00;
send_buf[send_len++] = 0x00;
send_buf[send_len++] = 0x00;
//设置GPS相关信息
//读取天线信息,是否定位
GPSLocate = 0;//默认定位为0

char set_config = 0x0;

char flag = 0x00; //拼凑8位二进制的标志

if(0 == GPSLocate) //定位 //0000 0 0/1 0/1 0
{
set_config = 0x0;
}else if(1 == GPSLocate)//未定位 //0001 0 0/1 0/1 0
{
set_config = 0x10;
}
if(0 == North_flag)
{
flag = 0xfb;
set_config = set_config & flag;
printf("[0x%02x]\n",set_config);
}else if(1 == North_flag){
flag = 0x04;
set_config = set_config | flag;
printf("[0x%02x]\n",set_config);
}
if(0 == South_flag){
flag = 0xfd;
set_config = set_config & flag;
printf("[0x%02x]\n",set_config);
}else if(0 == South_flag){
flag = 0x02;
set_config = set_config | flag;
printf("[0x%02x]\n",set_config);
}
send_buf[send_len++] = set_config;
//经度
tmp_data.u__i = longtitude;
send_buf[send_len++] = (tmp_data.s.s3 &0xff);
send_buf[send_len++] = (tmp_data.s.s2 &0xff);
send_buf[send_len++] = (tmp_data.s.s1 &0xff);
send_buf[send_len++] = (tmp_data.s.s0 &0xff);

//纬度
tmp_data.u__i = latitude;
send_buf[send_len++] = (tmp_data.s.s3 &0xff);
send_buf[send_len++] = (tmp_data.s.s2 &0xff);
send_buf[send_len++] = (tmp_data.s.s1 &0xff);
send_buf[send_len++] = (tmp_data.s.s0 &0xff);


break;
case 0x0d: //13
printf("0x0d\n");
//发送0x0a,将ACU设备信息发送给VSAT
//send_buf[send_len++] = 0x16;
send_buf[send_len++] = 0x0a;//协议命令
send_buf[send_len++] = 0x02;
send_buf[send_len++] = 0xff;//ACU ID
send_buf[send_len++] = buf[9];
send_buf[send_len++] = 0x01;
//最后一次接收到的VACP发来的Seq_num
send_buf[send_len++] = buf[11];
send_buf[send_len++] = buf[12];
send_buf[send_len++] = buf[13];
send_buf[send_len++] = buf[14];

send_buf[send_len++] = 0x01;
send_buf[send_len++] = 0x00;
send_buf[send_len++] = 0x08;
send_buf[send_len++] = 0x30;
send_buf[send_len++] = 0x30;
send_buf[send_len++] = 0x2e;
send_buf[send_len++] = 0x30;
send_buf[send_len++] = 0x31;
send_buf[send_len++] = 0x2e;
send_buf[send_len++] = 0x30;
send_buf[send_len++] = 0x38;
send_buf[send_len++] = 0x02;
send_buf[send_len++] = 0x33;

break;
case 0x0e: //14
printf("0x0e\n");
break;
default:
break;

}
send_buf[5] = send_len - 6;//有效长度
*sendlen = send_len;
}
void GetAntInfo_func()
{
//1、读取板子的IP地址
//RetAntIP();
//int ret = 0;
//2、读取天线的信息
int sock_fd = 0;
int read_num = 0;
int i = 0;
char *server_ip = "127.0.0.1";
char *whick_cgi = "monitor";
char *whick_cmd = "Sta?";
char buf[128] = {0};
char read_buf[512] = {0};
char read_buf_cut[512];

char az_inf[10]={0};

char *strr = NULL;

sock_fd = client_init(80, server_ip);
if(sock_fd <= 0){
perror("client_init");
}
snprintf(buf,128,"POST /cgi-bin/cmdack.cgi HTTP/1.1\r\nHost:%s\r\nContent-Length:4\r\nReferer:/cgi-bin/%s.cgi\r\n\r\n%s",server_ip,whick_cgi, whick_cmd);
//printf("%s\n", buf);
//printf("getAntsatatus\n");

my_write(sock_fd, buf, strlen(buf));
bzero(read_buf, 512);
while(1){
read_num += read(sock_fd, &read_buf[read_num],(511-read_num));
usleep(1000);
if(read_num > 100){
break;
}else;
}

for(i =0 ; i < (read_num-5); i++){
if(read_buf[i] == ‘/‘&&read_buf[i+4] == ‘l‘){
break;
}else;
}
//printf("printf data,read_buf_len = %d\n",strlen(read_buf));

//printf("read_buf = %s\n", read_buf);
if(strstr(read_buf,"502 Bad Gateway") == NULL)
{

//如果可以得到网页返回的数据,则提取串口要发送的数据信息
strcpy(read_buf_cut,strstr(read_buf,"text/html")+9);

//printf("read_buf = %c,len = %d\n", read_buf_cut[3],strlen(read_buf_cut));
//printf("----------------------\n");
if(read_buf_cut[3] == ‘R‘ && strlen(read_buf_cut) > 102)
{
//地理经度10倍
strr = strchr(read_buf_cut,‘J‘);
bzero(az_inf, 10);
strncpy(az_inf,strr+1,4);
//printf("long_inf = %s\n",az_inf);
if(az_inf != NULL){
//ant_inf.longtitude = atoi(az_inf);
getant_info.longtitude = atoi(az_inf);
//printf("getant_info.longtitude = %d\n",getant_info.longtitude);
}
//地理纬度10倍
strr = strchr(read_buf_cut,‘W‘);
bzero(az_inf, 10);
strncpy(az_inf,strr+1,3);
//printf("lat_inf = %s\n",az_inf);
if(az_inf != NULL){
//ant_inf.latutide = atoi(az_inf);
getant_info.latutide = atoi(az_inf);
//printf("getant_info.latutide = %d\n",getant_info.latutide);
}
//海拔高度10倍
strr = strchr(read_buf_cut,‘M‘);
bzero(az_inf, 10);
strncpy(az_inf,strr+4,4);
//printf("alt_inf = %s\n",az_inf);
if(az_inf != NULL){
//ant_inf.latutide = atoi(az_inf);
getant_info.altitude = atoi(az_inf);
//printf("getant_info.altitude = %d\n",getant_info.altitude);
}

}

}

close(sock_fd);
}
void listen_web(void)
{
while(1)
{
GetAntInfo_func();
}
}
void listen_sock(void)
{
//创建socket
int sockfd=socket(AF_INET,SOCK_STREAM,0);
int new_sd;
char buf[MAXDATASIZE]={0};
char send_buf[MAXDATASIZE]={0};
//char str[]={0x01,0x02,0x03,0x04,0x05,0x06,0xff,0xfc,0x18};
//char str9[]={0xde,0xad,0xbe,0xef,0x00,0x16,0x09,0x02,0xff,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x05,0xff,0xff,0xfc,0x19,0x01,0xff,0xff,0xfc,0x18};
int ret;
//int pos=0,size;
int i,sendlen;

if(sockfd==-1)
{
perror("sockfd failed!");
exit(-1);
}
//准备地址
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT);//host to net short
//inet_aton("127.0.0.1",&addr.sin_addr);
addr.sin_addr.s_addr = INADDR_ANY;
//绑定
int res=bind(sockfd,(struct sockaddr *)&addr,sizeof(addr));
if(res==-1)
{
perror("bind failed!");
exit(-1);
}
//监听端口
if(listen(sockfd,100)==-1)//最多连接的设备100
{
perror("listen failed!");
exit(-1);
}
//等待客户端连接
struct sockaddr_in fromaddr;//客户端地址
//循环监听读取
while(1)
{
socklen_t len=sizeof(fromaddr);//len不能初始化为0
new_sd=accept(sockfd,(struct sockaddr *)&fromaddr,&len);
if(new_sd==-1)
{
perror("accept failed!");
exit(-1);
}
char *from_ip=inet_ntoa(fromaddr.sin_addr);

printf("connect IP:%s\n",from_ip);
//printf("port = %s\n",fromaddr.sin_port);

//sleep(3);
//处理客户端数据
#if 1

//1、接收
memset(buf,100,0);
ret=read(new_sd,buf,sizeof(buf));
if(ret<0)
{
perror("read failed!");
exit(-1);
//break;
}
else{
printf("data from VSAT,len = %d\n",ret);
for(i=0;i<ret;i++){
printf("[%02x] ",buf[i]);
}
printf("\n");

}
//2、解析
memset(send_buf,MAXDATASIZE,0);
Analysis_VACP(buf, send_buf, &sendlen);
printf("sendlen=%d\nACU send: ",sendlen);
for(i=0;i<sendlen;i++){
printf("[%02x] ",send_buf[i]);
}
printf("\n");

//发送
send(new_sd, send_buf, sendlen, 0);
sleep(2);
#else
memset(buf,100,0);
ret=read(new_sd,buf,sizeof(buf));
if(ret<0)
{
perror("read failed!");
exit(-1);
//break;
}
else{
printf("data from VSAT,len = %d\n",ret);
for(i=0;i<ret;i++){
printf("[%02x] ",buf[i]);
}
printf("\n");

}

#if 1
size = sizeof(str9);
while(size)
{
ret = write(new_sd,str9+pos,size);
if(ret < 0)
{
;
}else;
size -= ret;
pos += ret;
}
#endif
#endif
//关闭连接
close(new_sd);
}
close(sockfd);
}

pthread_attr_t attr1;
pthread_attr_t attr2;

void Thread_Init(void)
{
int ret;
//1、获取天线的状态信息并保存在共享内存
//创建线程1
pthread_t antmsg_id, sock_id;

pthread_attr_init(&attr1); // init struct
pthread_attr_setschedpolicy(&attr1, SCHED_OTHER);

ret = pthread_create(&antmsg_id, &attr1, (void *)listen_web , NULL); // process
if (ret != 0){
printf(("pthread listen_web error"));
}else
printf(("pthread listen_web creat ok!"));
pthread_attr_destroy(&attr1); // delect struct


//创建线程2 与modem通信
pthread_attr_init(&attr2); // init struct
pthread_attr_setschedpolicy(&attr2, SCHED_OTHER);

ret = pthread_create(&sock_id, &attr2, (void *)listen_sock , NULL); // process
if (ret != 0){
printf(("pthread listen_sock error"));
}else
printf(("pthread listen_sock creat ok!"));
pthread_attr_destroy(&attr2); // delect struct


pthread_join(antmsg_id, NULL);
pthread_join(sock_id, NULL);

}

int main()
{
Thread_Init();//初始化线程

while(1);
return 0;
}

以上是关于socket的主要内容,如果未能解决你的问题,请参考以下文章

socket通信

java实例检查端口是否被占用

网络通信与Socket

分布式理论,架构设计Socket和IO模型

分布式理论,架构设计Socket和IO模型

android做一个简单上传文件的功能,socket连接问题