Winsock C ++ - Java连接速度慢

时间:2016-05-31 17:00:12

标签: java c++ performance server winsock

我正在PC上运行服务器(C ++ Winsock)和客户端(Java)。

我正在从客户端向服务器发送一个大字节数组,并且传输完成时没有任何错误,我的传输速度非常慢。举个例子,对于200.000字节的数组大小,传输需要3-5秒(大约50kB / s)。

这是正常的吗?我不是专家,但我不应该通过局域网达到更高的速度(大约1Mb / s)?

这是我的简化代码:

客户端(Java)

    import ...

    public class Client {
        public static void main(String[] args) throws IOException {

            OutputStream outToServer;
            DataOutputStream out = null; 
            String serverHostname = new String ("...");
            int port = ...;

            Socket client = null;
            try {
                client = new Socket(serverHostname, port);
                outToServer = client.getOutputStream();
                out = new DataOutputStream(outToServer);

                int size = 200000;
                byte[] b = new byte[size];
                new Random().nextBytes(b);
                for(int i = 0 ; i < size ; i++){
                    out.writeByte(b[i]);
                }           
                out.close();
            } catch (UnknownHostException e) ...//Exit
              catch (IOException e) ...//Exit

            client.close();
        }
    }

和Server(C ++,Winsock)

    #undef UNICODE
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    #include <winsock2.h>
    #include <ws2tcpip.h>...
    // Need to link with Ws2_32.lib
    #pragma comment (lib, "Ws2_32.lib")
    // #pragma comment (lib, "Mswsock.lib")
    #define DEFAULT_BUFLEN 512
    #define DEFAULT_PORT "..."

    int __cdecl main(void)
    {
        WSADATA wsaData;
        int iResult;
        SOCKET ListenSocket = INVALID_SOCKET;
        SOCKET ClientSocket = INVALID_SOCKET;
        struct addrinfo *result = NULL;
        struct addrinfo hints;
        int iSendResult;
        char recvbuf[DEFAULT_BUFLEN];
        int recvbuflen = DEFAULT_BUFLEN;

        // Initialize Winsock
        iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (iResult != 0) //Return

        ZeroMemory(&hints, sizeof(hints));
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;
        hints.ai_flags = AI_PASSIVE;

        // Resolve the server address and port
        iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
        if (iResult != 0) ...//Return

        // Create a SOCKET for connecting to server
        ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
        if (ListenSocket == INVALID_SOCKET) ...//Return

        // Setup the TCP listening socket
        iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
        if (iResult == SOCKET_ERROR) ...//Return

        freeaddrinfo(result);

        iResult = listen(ListenSocket, SOMAXCONN);
        if (iResult == SOCKET_ERROR) ...//Return

        // Accept a client socket
        ClientSocket = accept(ListenSocket, NULL, NULL);
        if (ClientSocket == INVALID_SOCKET) ...//Return

        // No longer need server socket
        closesocket(ListenSocket);
        // Receive until the peer shuts down the connection
        int bytes = 0;
        do {
            iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
            if (iResult > 0) 
                bytes += iResult;
            else if (iResult == 0)
                //Connection Closing
            else  
                ...//Return

        } while (iResult > 0);

        printf("Received %d bytes\n", bytes);

        ...//Shutdown and Return
    }

1 个答案:

答案 0 :(得分:0)

OutputStream包裹在BufferedOutputStream中,或者只是手动缓冲输出(例如,首先将字节收集到一个数组中,然后使用#write(byte[])。每个字节发送一个数据包一定非常慢 - 请参阅Size of empty UDP and TCP packet?;空TCP数据包为64字节,为1字节数据发送64 + 1字节,为您提供~1 / 65的可能传输速率( YMMV,由于消除了VM的额外大量开销 - >每个writeByte命令的OS通信,你可能会看到传输速率更高的增长。

直接&#39;净转移的经验法则是,如果您打算发送比通常的以太网数据包少得多(即明显小于1KiB,例如100字节)重复时间段,最好先缓冲它并集体发送。