Java -> C++ TCP 套接字直到关闭才发送

标签 java c++ sockets tcp stream

我面临另一个 TCP 套接字问题。 我已经阅读了大量问题和类似问题的答案,但我的问题有些不同。

我有一个 Java 客户端和一个 C++ 服务器。一切都按预期进行,直到我使用不同的机器(到目前为止与其他问题相同) 来自客户端的消息似乎卡在了 den TCP 缓冲区中。当我最终关闭套接字时,所有内容都发送到服务器。但是这些单个消息是控制消息,所以我需要立即发送它们。据我所知,这是预期的行为,但我如何发送可靠的控制消息。

有没有办法强制发送消息。 (我可以让套接字打开几分钟,但不会发送任何内容。)

有什么问题吗? (见以下代码)

我每次都必须关闭套接字才能执行真正的冲洗吗?

我应该使用 UDP 来代替协议(protocol)工作吗?

Java代码:

mSocketSend = new Socket();
mSocketSend.connect(new InetSocketAddress(mServerIp, mSocketPortSend), mTimeOut);
PrintWriter pw = new PrintWriter(mSocketSend.getOutputStream(), true);
pw.println(data);

C++代码:

   opening socket...(i leave that)
   char* buffer = new char[1024];
   int rc = recv(mConnectedSocket, buf, 1024, 0);

如果你想要更多。写下来。我几乎把所有东西都留下了。 ^^ 我认为它不相关。通信通常很顺利。完全没有错误。所以它只是这个 TCPBuffer 东西。

我知道应该有一些分隔符或消息长度的东西。但实际上:不发送的消息长度没有帮助。 ^^

感谢您的帮助。

编辑#01 整串代码:

mSocket->createSocketServer(22);
    char* buffer = new char[1024];
 while(true){

        int numberBytes = mSocket->receiveChars(buffer, 1024);

        if (numberBytes > 0){
            uninterestingHandlingFunction(buffer);
        }else{
            mSocket->createSocketServer(22);
        }
    }

bool Socket::createSocketServer(u_short port)
{
    if (mConnectedSocket != INVALID_SOCKET)
    {
        closesocket(mConnectedSocket);
    }

    if (s == INVALID_SOCKET)
    {
        WSADATA wsa;

        if (WSAStartup(MAKEWORD(2,0), &wsa) != 0)
            return 0;

        s = socket(AF_INET, SOCK_STREAM, 0);
        if (s == INVALID_SOCKET)
            return 0;

        SOCKADDR_IN addr;
        memset(&addr, 0, sizeof(SOCKADDR_IN));
        addr.sin_family=AF_INET;
        addr.sin_port=htons(port);
        addr.sin_addr.s_addr=ADDR_ANY;

        if (bind(s, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
        {
            s = INVALID_SOCKET;
        } else if (listen(s, 10) == SOCKET_ERROR)
        {
            s = INVALID_SOCKET;
        }

        if (s == INVALID_SOCKET)
        {
            closesocket(s);
            return 0;
        }
    }
    mConnectedSocket = accept(s, NULL, NULL);

    if (mConnectedSocket == INVALID_SOCKET)
    {
        closesocket(s);
        return 0;
    }
    return 1;
}

int Socket::receiveChars(char* buf, unsigned maxSize)
{
    if (mConnectedSocket == INVALID_SOCKET)
        return -1;

    int rc = recv(mConnectedSocket, buf, maxSize, 0);
    if (rc == SOCKET_ERROR)
    {
        std::cout << "Socket: error " << WSAGetLastError() << std::endl;
    }
    return rc;
}

你想要它....

编辑 #2 再试一次

我尝试了更多的东西。 起初:这个问题不是每次都出现在真实网络连接的设备上。 -> 完全重启客户端和服务器 -> 问题没有发生 -> 完全重启客户端和服务器 -> 出现问题

可悲的是,我不知道该从这个习惯中吸取什么。

我偶然发现的另一件事是绑定(bind)和监听套接字(在 Code SOCKET 中)。此套接字监听连接,如果工作线程需要新连接(在启动时或如果前一个关闭),则套接字 s 将下一个排队的连接提供给 mConnectedSocket 以进行接收,其他连接在处理一个连接时积压。 从 Java View 来看:连接了一个套接字(设备 A)。下一个套接字(设备 B)尝试连接。 -> 连接成功(如果确实发生这种情况,它会在代码中得到适当控制)-> 然后以自然物质发送数据。 (socket在c++端还在积压)

好吧,这很难转变为我所经历的习惯。我会尝试表达我的想法。 Javaside:创建PrintWriter。提供数据并刷新。因为连接没有完全建立(C++ 端没有额外的 connectedSocket)。冲洗不起作用。 onClose 套接字最终刷新其内容。

如果你这么认为,请告诉我闭嘴。我真的不知道“连接积压”在实现中实际上意味着什么“^^

我知道,我应该为每个连接打开一个新线程,但我现在不能。所以坚持使用这个服务器代码。

最佳答案

您需要执行一个 flush(),将数据推出。

关于Java -> C++ TCP 套接字直到关闭才发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10659361/

相关文章:

java - 如何将 "this"传递到 Action 监听器中

c - 套接字代码在 main 中工作,但在其他功能中失败

sockets - HAProxy 无法启动,无法绑定(bind) UNIX 套接字 [/run/haproxy/admin.sock]

java - java中的retainAll非常慢......有没有更快的方法?

Java转换日期格式

java - 无法在 Java 中初始化静态成员 - Android

c++ - 在 C++ 中比较两种数据类型?

c++ - QImage 与 QThreads

c++ - 整数溢出问题

c++ - 如何为套接字设置多个路由条目?