我的任务是编写一些软件来从我们的嵌入式 linux 设备与服务器进行通信。我要与之通信的服务器使用严格的协议,该协议非常模糊和专有 - 我不想在这里命名它,因为这些信息可能对我工作的公司很敏感。
所以数据必须是 4 位半字节 (N)、32 位无符号整数 (U)、32 位有符号整数 (S)、8 位无符号整数 (X) 和字符 (C) 的形式。例如,一个简化的登录结构可能是 NNNN-用户 ID,后跟 XX-更多数据,CCCC-访问代码。所以我需要按顺序发送 NNNNXXCCCC 才能登录。
数据需要通过 UDP 发送,然后在同一端口上侦听确认。所以我这样做的方式是我编写了一个send_and_receive
函数,然后编写了一个结构,将结构发送到服务器。
typedef u_int8_t NN;
typedef u_int8_t X;
typedef int32_t S;
typedef u_int32_t U;
typedef char C;
#pragma pack(1)
typedef struct{
NN user_id[2];
X some_data[2];
C access_code[4];
} LogOnRequest;
然后我声明并填写结构的信息并使用此函数发送它:
void send_and_receive(void* message, void* reply, int do_send, int expect_reply){
struct sockaddr_in serv_addr;
int sockfd, i, slen=sizeof(serv_addr);
int buflen = BUFLEN;
void* buf = NULL;
if ( (strlen(message)) >= BUFLEN)
err("Message too big");
buf = malloc(buflen);
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
err("socket");
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if (inet_aton(IP_ADDRESS, &serv_addr.sin_addr)==0)
err("inet_aton() failed\n");
if(do_send == TRUE){
strcpy(buf, message);
if (sendto(sockfd, buf, buflen, 0, (struct sockaddr*)&serv_addr, slen)==-1)
err("sendto()");
}
if (expect_reply == TRUE){
if (recvfrom(sockfd, buf, buflen, 0, (struct sockaddr*)&serv_addr, &slen)==-1)
err("recvfrom()");
}
memcpy(reply, buf, BUFLEN);
close(sockfd);
free(buf);
}
现在,当我这样做时,我没有得到任何回复,也没有注意到服务器上已收到数据包。基本上我想知道我这样做是否正确,有没有更好的方法呢?是否可以使用 bash 脚本做同样的事情?
任何反馈都会很棒,因为我在这方面感觉不够深入。