套接字Java到C++-消息的长度总是8192个字符



我正在实现从java到C++程序的TCP套接字连接。目前,这是一种方式,但总有一天会变成双向的。我的消息很长(约100000个字符)。不知怎么的,我的应用程序一次只发送8192个字符/字节。怎么可能呢?有什么工具可以帮助调试吗?客户端和服务器都在本地windows计算机上运行。我不熟悉网络编程,所以任何帮助都将不胜感激!提前感谢!

这是我到目前为止的代码:

JAVA:
建立连接:

try {
            serverSocket = new ServerSocket(socketPort);
            System.out.println("waiting for client ...");
            while (true) {
                clientSocket = serverSocket.accept();
                System.out.println("client connected.");
                if (clientSocket!=null) break;
            }
        }
        catch (IOException e) {
           System.out.println(e);
        }

发送东西:

OutputStream out = clientSocket.getOutputStream();
BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream()));
//send the new data to client
PrintWriter pw = new PrintWriter(out, true);
String outString = "VERY LONG TEXT ENDING WITH SPECIAL LETTER LIKE $";
pw.println(outString);

C++:

建立连接

bool connectToHost(int PortNo, char* IPAddress)
{
    //Start up Winsock…
    WSADATA wsadata;
    int error = WSAStartup(0x0202, &wsadata);
    //Did something happen?
    if (error)
        return false;
    //Did we get the right Winsock version?
    if (wsadata.wVersion != 0x0202)
    {
        WSACleanup(); //Clean up Winsock
        return false;
    }
    //Fill out the information needed to initialize a socket…
    SOCKADDR_IN target; //Socket address information
    target.sin_family = AF_INET; // address family Internet
    target.sin_port = htons (PortNo); //Port to connect on
    target.sin_addr.s_addr = inet_addr (IPAddress); //Target IP
    mSocket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); //Create socket
    if (mSocket == INVALID_SOCKET)
    {
        return false; //Couldn't create the socket
    }  
    //Try connecting...
    if (connect(mSocket, (SOCKADDR *)&target, sizeof(target)) == SOCKET_ERROR)
    {
        return false; //Couldn't connect
    }
    else
        return true; //Success
}

接收东西:

if (connectToHost(3141, "127.0.0.1")) 
    {
        int iResult;
        char recvbuf[DEFAULT_BUFLEN]; // DEFAULT_BUFLEN = 1000000
        // Receive until the peer closes the connection
        do {
            iResult = recv(mSocket, recvbuf, DEFAULT_BUFLEN, 0); // DEFAULT_BUFLEN = 1000000
            if ( iResult > 0 )
            {                 
                std::cout<<"recvbuf: "<< recvbuf[strlen(recvbuf)-1]<<""<< std::endl;  //not the last character that I sent, but supposed to be
                std::cout<<"recvbuf size: "<< iResult <<""<< std::endl; //fist are 8192 and then add up until sent size 
            }
            else if ( iResult == 0 )
                printf("Connection closedn");
            else
                printf("recv failed with error: %dn", WSAGetLastError());
        } while( iResult > 0 );
    } else 
    {
        printf("connect failedn");
    }

TCP套接字使用字节流概念。TCP套接字确保数据以字节流的形式无错误、有序地到达。发送方向TCP字节流添加字节,套接字负责将它们发送到目的地。套接字不会分离您的逻辑消息;您有责任为嵌入字节流中的任何逻辑消息插入分隔符。TCP套接字不一定每次向套接字写入字节时都会在套接字上发送数据包。这是为了提高效率,通过数据字节数与发送的总字节数(数据+开销)来衡量。您可以阅读Nagle的TCP算法。

当从套接字读取时,您将再次消耗字节流。您需要调用receive的次数可能与调用send的次数不匹配。但是您知道正确的字节将按顺序传递,并且这些字节的数量将与发送的字节相同。

大小8192可能是触发发送数据包的缓冲区大小。

如果只发送1个字节,然后刷新套接字,那么在接收端应该只看到一个字节。您还可以通过在java套接字选项中设置TCP_NODELAY来禁用Nagle的算法。

一次接收的内容不能超过套接字接收缓冲区中的内容。使用setsockopt()将套接字接收缓冲区大小从8192提高,并在发送端对套接字发送缓冲区执行相同操作。

最新更新