Java->;C++;TCP套接字在关闭之前不会发送

Java->;C++;TCP套接字在关闭之前不会发送,java,c++,sockets,tcp,stream,Java,C++,Sockets,Tcp,Stream,我面临另一个TCP套接字问题。 我已经阅读了大量的问题和类似问题的答案,但我的问题在某种程度上是不同的 我有java客户端和C++服务器。在我使用不同的机器之前,一切都按预期进行(与到目前为止的其他问题相同) 来自客户端的消息似乎卡在den TCP缓冲区中。当我最终关闭套接字时,所有内容都被发送到服务器。但是这些单一的消息是控制消息,所以我需要立即发送它们。据我所知,这是预期的行为,但我如何发送可靠的控制消息 是否有办法强制发送消息。(我可以让插座保持打开状态几分钟,而不发送任何内容。) 有什么

我面临另一个TCP套接字问题。 我已经阅读了大量的问题和类似问题的答案,但我的问题在某种程度上是不同的

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

是否有办法强制发送消息。(我可以让插座保持打开状态几分钟,而不发送任何内容。)

有什么不对劲吗?(参见以下代码)

我是否每次都必须关闭插座才能进行真正的冲洗

我是否应该使用UDP,并进行额外的协议工作

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);
如果你想要更多。写下来。我几乎什么都漏掉了。^^我认为这不相关。3.通常情况下,沟通都很好。。完全没有错误。所以这只是一个垃圾桶

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

谢谢你的帮助

编辑#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;
}
mSocket->createSocketServer(22);
char*buffer=新字符[1024];
while(true){
int numberBytes=mSocket->receiveChars(缓冲区,1024);
如果(字节数>0){
无中断处理功能(缓冲区);
}否则{
mSocket->createSocketServer(22);
}
}
布尔套接字::createSocketServer(u_短端口)
{
if(mConnectedSocket!=无效的_SOCKET)
{
闭合插座(mConnectedSocket);
}
if(s==无效的_套接字)
{
WSADATA wsa;
if(WSAStartup(MAKEWORD(2,0),&wsa)!=0)
返回0;
s=套接字(AF_INET,SOCK_STREAM,0);
if(s==无效的_套接字)
返回0;
地址中的SOCKADDR_;
memset(&addr,0,sizeof(SOCKADDR_IN));
地址sinu family=AF\u INET;
地址sin_端口=htons(端口);
addr.sin\u addr.s\u addr=addr\u ANY;
if(bind(s,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN))==SOCKET_错误)
{
s=无效的_插座;
}否则如果(侦听(s,10)=套接字错误)
{
s=无效的_插座;
}
if(s==无效的_套接字)
{
插座;
返回0;
}
}
mConnectedSocket=accept(s,NULL,NULL);
if(mConnectedSocket==无效的_SOCKET)
{
插座;
返回0;
}
返回1;
}
int-Socket::receiveChars(char*buf,无符号maxSize)
{
if(mConnectedSocket==无效的_SOCKET)
返回-1;
int rc=recv(mConnectedSocket,buf,maxSize,0);
if(rc==SOCKET\u错误)
{
std::无法完全重新启动客户端和服务器->出现问题

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

我遇到的另一件事是绑定和侦听套接字(在代码套接字s中)。此套接字侦听连接,如果工作线程需要新连接(在启动时或之前的连接关闭时),则套接字s将下一个排队的连接提供给mConnectedSocket以进行recv,在处理一个连接时,其他连接将被积压。 从java视图中,一个套接字被连接(设备A)。下一个套接字(设备B)尝试连接。->连接成功(如果确实发生,它在代码中被适当控制)>接着在自然物质中发送数据(socket仍然在C++侧的积压)

嗯,这很难转变成我的习惯。我会尽量表达我的想法。 JavaPoT:创建了打印程序。用数据进行填充并刷新。因为连接没有完全建立(C++边没有附加的连接插槽)。刷新不起作用。关闭套接字最后刷新其内容。

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

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

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

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

PrintWriter.flush();
或者使用自动冲洗的书写器

您还应该确保服务器读取一行(直到\n)而不是完整的1024个字符,但是我不知道recv()的作用,所以我不知道

PrintWriter pw = new PrintWriter(mSocketSend.getOutputStream(), true);
pw.println(data);
pw.flush();
或者使用自动冲洗的书写器


您还应该确保服务器读取一行(直到\n)而不是完整的1024个字符,但我不知道recv()的作用,所以我不知道这一点。

因为您正在使用自动刷新,甚至尝试使用显式的
刷新()

PrintWriter pw = new PrintWriter(mSocketSend.getOutputStream(), true);
pw.println(data);
pw.flush();
可能是因为您没有打开inputStream。请尝试执行
getInputStream()

否则,您是否尝试过:

  • 不使用
    connect
    而直接在
    Socket
    构造函数中给出参数的任何差异

  • setTcpNoDelay
    在套接字上(但不应导致几分钟的延迟!!)


  • 由于您正在使用自动刷新,甚至尝试使用显式的
    flush()

    可能是因为您没有打开inputStream。请尝试执行
    getInputStream()

    否则,您是否尝试过:

  • 不使用
    connect
    而直接在
    Socket
    构造函数中给出参数的任何差异

  • setTcpNoDelay
    在套接字上(但不应导致几分钟的延迟!!)


  • 事实上,你的问题可能在接收端,你的
    recv
    需要处于一个循环中(你可以在谷歌上搜索这个例子)。没有任何保证,每个都不太可能