使用 C 中的 UDP 从客户端传输 Bool 数组
Bool array transfer from client with UDP in C
我需要创建一个简单的 modbus 应用程序,它将以 bool 类型传输数据。我为此创建了客户端和服务器代码。
客户端:
int Client(bool message[8])
{
struct sockaddr_in si_other;
int s, slen=sizeof(si_other);
bool buf[BUFLEN];
WSADATA wsa;
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
exit(EXIT_FAILURE);
return 1;
}
if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
{
exit(EXIT_FAILURE);
return 2;
}
memset((bool *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);
if (sendto(s, message, strlen(message) , 0 , (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
{
exit(EXIT_FAILURE);
return 3;
}
// closesocket(s);
// WSACleanup();
return 0;
}
服务器端:
int main()
{
SOCKET s;
struct sockaddr_in server, si_other;
int slen , recv_len;
bool buf[BUFLEN];
WSADATA wsa;
slen = sizeof(si_other) ;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
if((s = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
}
printf("Socket created.\n");
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( PORT );
if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
puts("Bind done");
while(1)
{
printf("Waiting for data...\n");
fflush(stdout);
memset(buf,'0', BUFLEN);
if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
for (int i=0; i<=7; i++) {
printf("%d", buf[i]);
}
printf("Data: %d\n" , buf);
printf("%s-%s-%s\n",buf[0],buf[1],buf[2]); //When I run this code, it works just like the code with 'for' and gives an error.
if (sendto(s, buf, recv_len, 0, (struct sockaddr*) &si_other, slen) == SOCKET_ERROR)
{
printf("sendto() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
}
closesocket(s);
WSACleanup();
return 0;
}
当我运行申请时,数据传输不正确。例如,当我发送数据为'101010'时,它发送'100000';如果发送数据为“110101”,则发送“110000”,如果发送为“011111”,则发送“000000”。换句话说,为了正确读取值为'1'的数据,该数据之前的所有值都必须为'1'。
当我删除代码中的 'for' 部分并尝试直接读取整个 buf ( printf("Data: %d\n" , buf) ) 时,它读取 '6421972' 数据.即使我更改数据,这个数字也不会改变。我该怎么做才能克服这个问题?
在您的客户端中,strlen(message) 将对字符进行计数,直到遇到第一个“0”。因此,您发送的布尔数组 never 的长度为 8.
然后您的客户端必须在参数中也采用缓冲区长度来解决此问题。
如果您的缓冲区是真正的 C 数组(不是分配的指针),那么 sizeof 语句可以给出长度。但是如果你对 buf 使用 malloc 指针,sizeof 语句将总是 return 8,从不小于,从不大于(在 64 位系统中),这只是指针的大小。
简而言之,始终保留一个长度整数和一个缓冲区。
我需要创建一个简单的 modbus 应用程序,它将以 bool 类型传输数据。我为此创建了客户端和服务器代码。 客户端:
int Client(bool message[8])
{
struct sockaddr_in si_other;
int s, slen=sizeof(si_other);
bool buf[BUFLEN];
WSADATA wsa;
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
exit(EXIT_FAILURE);
return 1;
}
if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
{
exit(EXIT_FAILURE);
return 2;
}
memset((bool *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);
if (sendto(s, message, strlen(message) , 0 , (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
{
exit(EXIT_FAILURE);
return 3;
}
// closesocket(s);
// WSACleanup();
return 0;
}
服务器端:
int main()
{
SOCKET s;
struct sockaddr_in server, si_other;
int slen , recv_len;
bool buf[BUFLEN];
WSADATA wsa;
slen = sizeof(si_other) ;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
if((s = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
}
printf("Socket created.\n");
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( PORT );
if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
puts("Bind done");
while(1)
{
printf("Waiting for data...\n");
fflush(stdout);
memset(buf,'0', BUFLEN);
if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
for (int i=0; i<=7; i++) {
printf("%d", buf[i]);
}
printf("Data: %d\n" , buf);
printf("%s-%s-%s\n",buf[0],buf[1],buf[2]); //When I run this code, it works just like the code with 'for' and gives an error.
if (sendto(s, buf, recv_len, 0, (struct sockaddr*) &si_other, slen) == SOCKET_ERROR)
{
printf("sendto() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
}
closesocket(s);
WSACleanup();
return 0;
}
当我运行申请时,数据传输不正确。例如,当我发送数据为'101010'时,它发送'100000';如果发送数据为“110101”,则发送“110000”,如果发送为“011111”,则发送“000000”。换句话说,为了正确读取值为'1'的数据,该数据之前的所有值都必须为'1'。
当我删除代码中的 'for' 部分并尝试直接读取整个 buf ( printf("Data: %d\n" , buf) ) 时,它读取 '6421972' 数据.即使我更改数据,这个数字也不会改变。我该怎么做才能克服这个问题?
在您的客户端中,strlen(message) 将对字符进行计数,直到遇到第一个“0”。因此,您发送的布尔数组 never 的长度为 8.
然后您的客户端必须在参数中也采用缓冲区长度来解决此问题。
如果您的缓冲区是真正的 C 数组(不是分配的指针),那么 sizeof 语句可以给出长度。但是如果你对 buf 使用 malloc 指针,sizeof 语句将总是 return 8,从不小于,从不大于(在 64 位系统中),这只是指针的大小。
简而言之,始终保留一个长度整数和一个缓冲区。