java - 为什么额外的数据被写入我的输出流以及如何阻止这种情况?

标签 java c sockets

我正在尝试在我的 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/

相关文章:

java - Firefox 启动等待 45 秒超时

java - Heroku 代码=H10 状态=503

java - Oracle JDeveloper 12C 和集成 Weblogic Server 未运行 Windows 10

c - 我需要帮助过滤 C 中的坏词吗?

c - 根据key进行归并排序

c++ - gcc 优化

c - 绑定(bind)错误 (99) : Cannot assign requested address

java - JPQL 查询属于另一个实体并满足某些条件的实体

java - 仅使用 Socket 类在 Java 中编写 HTTP 代理

sockets - conn (net.Conn) 并不总是写在套接字上