我正在尝试在我的 Java 服务器(它发送信息)和我的 C 客户端(它接收信息)之间建立一个简单的连接。
我想发送一个表示数组大小的整数,然后发送一个字节数组本身。我的 java 代码如下所示
Socket sc = new Socket("52.187.54.73", 19000);
while(true)
{
System.out.println("Socket open");
DataOutputStream outToClient = new DataOutputStream(sc.getOutputStream());
Random rand = new Random();
int rlen = rand.nextInt(10)%10 + 1;
byte[] a = new byte[rlen];
System.out.println("Size of the array is " + rlen);
for(int i = 0; i < rlen; i++)
a[i] = (byte)rand.nextInt(100);
outToClient.write(rlen);
outToClient.write(a,0,rlen);
//close socket
sc.close();
System.out.println("Done!");
//Break once done
break;
}
我的 C 代码如下所示
ptr1 = (void *)calloc(1, sizeof(int));
while(1){
sin_size = sizeof(client_addr);
connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size);
printf("\n Got a connection from (%s ,%d)",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
bytes_received = recv(connected,ptr1,10,0);
if(bytes_received<0){
printf("Something went wrong %s\n", strerror(errno));
}
printf("Bytes received: %d \n", bytes_received);
for(int i =0; i<bytes_received; i++){
unsigned char a = *(unsigned char *)(ptr1 + i*sizeof(unsigned char));
printf("Inc: %d", a);
}
假设上面的代码块有效,并且我能够获取 rlen
的值处理数组的代码如下:
ptr2 = calloc(rlen, sizeof(unsigned char));
bytes_received = recv(connected, ptr2, 1,0);// incoming, 0);
printf("bytes received: %d\n", bytes_received);
for(int i = 0; i < rlen; i++){
printf(" i = %d, val = %d\n ", i,*(unsigned char *)(ptr2 + i*sizeof(unsigned char)));
}
现在 Java 服务器发送一个 1 到 10 之间的数字。我之前尝试使用 int incoming = *(int *)ptr1;
读取发送的数字。但由于某种原因,偶尔我会得到巨大的值,例如 51020210
.
为了检查为什么会发生这种情况并进行调试,我编写了代码块:
for(int i =0; i<bytes_received; i++){
unsigned char a = *(unsigned char *)(ptr1 + i*sizeof(unsigned char));
printf("Inc: %d", a);
}
事实证明,有时发送的整数会变得非常大。
为什么会发生这种情况?在服务器端打印出rlen
显示了正确的值,但不确定地我在客户端获得了随机的非常大的值。
请注意,无论我在客户端收到什么数字,第一个数字的值都是 rlen
。
例如,如果 rlen
是 6,那么随机真正大的值类似于 689932423
稍后 rlen
的值将变得非常大,大约为 1000 秒,所以我需要解决这个问题,并且不能简单地获取我在客户端获得的任何内容的第一个字节。
最佳答案
我的代码的问题在于这一行,正如评论中正确指出的那样
bytes_received = recv(connected,ptr1,10,0);
我错误地尝试读取超过 4 个字节,这是转换为整数值所需的确切数字。
或者,要读取 4 个且仅 4 个字节,可以写为
bytes_received = recv(已连接, ptr1, 4, 0|MSG_WAITALL);
在 java 方面,正如注释中所指出的,函数 write(int)
仅发送 1 个字节。
要发送多个字节,首先必须将整数转换为 4 字节数组,然后必须像这样发送数组中的每个字节
outToClient.write(rlen_array, 0, 4);
关于java - 为什么额外的数据被写入我的输出流以及如何阻止这种情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39465160/