通过发送廉政插座从Java到C - 奇怪的结果 [英] Sending int via socket from Java to C - strange results

查看:218
本文介绍了通过发送廉政插座从Java到C - 奇怪的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用Java编写的一个简单的服务器,只是将一个整数连接的客户端。我用C写的一个客户端,连接到服务器,并打印出接收到的整数。

我的问题是所得到的结果而变化。大约有一半执行客户端我得到正确的结果(234)的时代,但有时我得到8323072。

这是服务器:

 类TCPSERVER {
  公共静态无效的主要(字符串ARGS [])抛出异常{
     ServerSocket的welcomeSocket =新的ServerSocket(6789);     而(真)
     {
        插座connectionSocket = welcomeSocket.accept();
        的System.out.println(welcomeSocket.accept()叫做);
        DataInputStream以inFromClient =新DataInputStream所(connectionSocket.getInputStream());
        DataOutputStream类outToClient =新的DataOutputStream类(connectionSocket.getOutputStream());        outToClient.writeInt(234);
     }
  }

}

这是客户端:

  INT主(INT ARGC,CHAR *的argv [])
{
    如果(argc个!= 4){
        printUsage();
        返回;
    }    字符*服务器IP =的argv [1];
    字符* serverPortC =的argv [2];
    字符* integerToSendC =的argv [3];    INT serverPort =的atoi(serverPortC);
    INT integerToSend =的atoi(integerToSendC);    INT socketDesc =插座(AF_INET,SOCK_STREAM,0);    如果(socketDesc℃,){
        的printf(创造插座\\ n时出错);
        返回;
    }    结构SOCKADDR_IN serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(serverPort);
    inet_pton(AF_INET,服务器IP,和放大器; serverAddr.sin_addr);    INT连接=连接(socketDesc,(结构sockaddr *)及serverAddr,sizeof的serverAddr);    如果(连接℃,){
        的printf(建立连接时出错\\ n时);
        返回;
    }    炭intBuffer [4];    如果(的recv(socketDesc,intBuffer,sizeof的intBuffer,0)== -1){
        的printf(错误而接收整数\\ n);
    }    INT receivedInt = ntohl(*(为(int *)及intBuffer));    的printf(收到INT数:%d \\ n,receivedInt);    关闭(socketDesc);
}

在此先感谢您的帮助!

编辑:
所以,最后我做了这样的事情,只是任何人谁都有同样的问题:

 而(receivedBytes 4;){
    INT的ReadBytes =读(receiverSocket,&安培; intBuffer,(sizeof的intBuffer) - receivedBytes,receivedBytes);
    receivedInteger + =(intBuffer&所述;≤(8 * receivedBytes));
    receivedBytes + =的ReadBytes;
}


解决方案

可以确保您收到的sizeof intBuffer 字节,在客户端?不,你不能,因为的recv()可能会返回更少的字节,然后要求。

mod您code循环周围的recv()只要少字节随后要求已收到,并没有出现错误。

注意的recv() ING 0 字节表示连接已被另一端关闭。

另外,还要确保在服务器端网络字节顺序发送。

此外^ 2:这是好主意,初始化变量( intBuffer 在这里),在开发阶段,至少会说:之前的调整阶段

I have a simple server written in Java, that just sends an Integer to a connected client. I have a client written in C, that connects to the server and prints out the received Integer.

My problem is that the result varies. About half of the times executing the client I get the correct result (234), but other times I get 8323072.

This is the server:

class TCPServer {
  public static void main(String args[]) throws Exception {
     ServerSocket welcomeSocket = new ServerSocket(6789);

     while(true)
     {
        Socket connectionSocket = welcomeSocket.accept();
        System.out.println("welcomeSocket.accept() called");
        DataInputStream inFromClient = new DataInputStream(connectionSocket.getInputStream());
        DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());

        outToClient.writeInt(234);
     }
  }

}

And this is the client:

int main(int argc, char *argv[])
{
    if(argc != 4){
        printUsage();
        return;
    }

    char* serverIP = argv[1];
    char* serverPortC = argv[2];
    char* integerToSendC = argv[3];

    int serverPort = atoi(serverPortC);
    int integerToSend = atoi(integerToSendC);

    int socketDesc = socket(AF_INET, SOCK_STREAM, 0);

    if(socketDesc < 0) {
        printf("Error when creating socket\n");
        return;
    } 

    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(serverPort);
    inet_pton(AF_INET, serverIP, &serverAddr.sin_addr);

    int connection = connect(socketDesc, (struct sockaddr*) &serverAddr, sizeof serverAddr);

    if(connection < 0) {
        printf("Error when establishing connection\n");
        return;
    }

    char intBuffer[4];

    if(recv(socketDesc, intBuffer, sizeof intBuffer, 0) == -1){
        printf("Error while receiving Integer\n");
    }

    int receivedInt = ntohl(*((int *) &intBuffer));

    printf("Received int: %d\n", receivedInt);

    close(socketDesc);
}

Thanks in advance for any help!

Edit: So in the end I did something like this, just for anybody who has the same problem:

while(receivedBytes < 4){
    int readBytes = read(receiverSocket, &intBuffer, (sizeof intBuffer) - receivedBytes, receivedBytes);
    receivedInteger += (intBuffer << (8*receivedBytes));
    receivedBytes += readBytes;
}

解决方案

Can you be sure you have received sizeof intBuffer bytes on the client side? No you can not, as recv() might return less bytes then requested.

Mod you code to loop around recv() as long as less bytes then requested have been received and no error occurred.

Note that recv()ing 0 bytes indicates the connection had been closed by the other side.

Also make sure the server side sends in network byte order.

Also^2: It is good idea to initialise variables (intBuffer here), at least during the development phase, will say: prior to the tuning phase.

这篇关于通过发送廉政插座从Java到C - 奇怪的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆