【问题标题】:Receiving wrong data on client side in socket communication在套接字通信中在客户端接收错误数据
【发布时间】:2015-10-24 12:48:43
【问题描述】:

我正在做一个小项目来确定网络的上传速度。我用 C 创建了一个小型服务器,它根据客户端发送的 1 MB 数据计算上传速度。

这是我的 C 语言服务器代码:

void main(int argc, char** argv){

    int sock_desc = 0;
    int connfd = 0;
    int read_size = 0;
    int clntSock; 
    struct sockaddr_in serv_addr;
    struct sockaddr_in echoClntAddr; 
    int rc;
    char client_message[1048576];//1048576 //524288
    time_t start,end;
    double t;
    int temp;
    double Bandwidth;
    int result[1];


struct timeval  tv1, tv2;

    sock_desc = socket(AF_INET, SOCK_STREAM, 0); 

    if(sock_desc < 0 )
       dieWithError("Unable to open Socket\n");

    memset(&serv_addr,0,sizeof(serv_addr)); 

    serv_addr.sin_family = AF_INET ;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(7024);

    if(bind(sock_desc, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) 
       dieWithError("bind failed\n");


    if(listen(sock_desc,MAX_CONNECTIONS) < 0)
       dieWithError("listen failed\n");  

       clntSock = sizeof(struct sockaddr);
 bahar: 
       connfd = accept(sock_desc, (struct sockaddr *)&echoClntAddr,(socklen_t*)&clntSock);
       printf("Connection accepted\n");
   while(1){

          read_size = recv(connfd , client_message ,1, 0); 
          gettimeofday(&tv1, NULL);
          if(read_size < 1048576)
read_again:  temp = read_size;
             read_size = 0;
             read_size = recv(connfd , client_message+temp , (sizeof(client_message)-temp), 0); 
             read_size+=temp;
             printf("read size is %d\n",read_size);
             temp=0;

             if(read_size < 1048576)//524288
                goto read_again; 


         gettimeofday(&tv2, NULL); 


        t =  (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 +
            (double) (tv2.tv_sec - tv1.tv_sec);

        read_size*=8;
        read_size/=1024;
          Bandwidth = read_size/t;
          result[0]= (int) Bandwidth;
        //  Bandwidth/=1024; 
          printf("Network Bandwidth is %d Kbps\n",result[0]);//Bandwidth);
          rc = send(connfd , result , 4, 0);//send Bandwidth to  client
          goto bahar;

           }

    }



    void dieWithError(char *errormsg){ 
         printf("%s", errormsg);    
    }

这是我的 Java 客户端代码:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;

public class JavaSAmpleClient {

    public static void main(String[] args)throws IOException {
        int i;
        int arr[] = new int[10];
        byte bfr[] = new byte[1024*1024];
        for (i=0;i<1048576;i++)
            bfr[i] = (byte)i;

  Socket s1 = new Socket("127.0.0.1",7024);


        BufferedOutputStream bos = new BufferedOutputStream(s1.getOutputStream());
                    BufferedInputStream bos1 = new BufferedInputStream(s1.getInputStream());
                    bos.write(bfr);
                    i=  bos1.read();//read bandwidth returned by server
                    System.out.println(i);

    }

}

面临的问题是,如果我用 C 语言编写客户端程序,它能够正确接收上传速度。但如果是 Java,我没有得到正确的结果。

例如: 如果是 java 客户端: 如果服务器将带宽发送为 4282279,Java 客户端将其接收为 167。

如果是 C 客户端: 如果服务器将带宽发送为 4282279,则客户端将其接收为 4282279。

我无法在 C 中进行客户端编程,因为我需要在 android 上运行客户端应用程序。

【问题讨论】:

  • 您似乎写入了多个字节,但您只读取了一个字节。我建议你阅读所有发送的字节。我还建议您将数据作为文本发送,因为这样更容易检查协议是否正确。顺便说一句 (byte) 4282279 == 167 所以我怀疑它正在正确读取第一个数字,而您需要的其余数字只需要多读一点。
  • 彼得打败我“使用文本而不是打包字节”。
  • @Peter 我现在应该如何更正?
  • 问题是我会做完全不同的事情。看看你的测试,它似乎是一种带宽测量。这通常由客户端完成,而不是服务器,因为客户端看到的带宽/延迟很重要。单独在服务器上进行测试可能会给您带来乐观的价值。另外我会根据带宽调整传输的大小,先尝试一条小消息,然后以指数方式增加大小以改善结果。这是因为您无法知道 1 MB 是太大还是太小,因为您没有测量连接速度
  • @effenok 我假设 4 个字节应该是二进制的 int。

标签: java c sockets


【解决方案1】:

C 发送代码中存在字节顺序问题,Java 代码中存在read() 编码问题。

  1. 您需要按网络字节顺序发送 int。在 C 代码中使用 result[0] = htonl(Bandwidth);
  2. 您正在读取一个字节而不是一个 4 字节整数。将DataInputStream 包裹在BufferedInputStream 周围,然后调用readInt()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-24
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    相关资源
    最近更新 更多