发送和接收所有数据(C ++套接字)

时间:2017-05-03 11:49:22

标签: c++ sockets

请帮助我找出客户端 - 服务器通信中的错误...

客户端使用此功能每秒25次从摄像机向服务器发送jpeg帧:

int SendAll(SOCKET &client_socket, string &data){
    int result, bytes_sent, sent_total, bytes_remain, package_size;
    result = bytes_sent = sent_total = package_size = 0;
    bytes_remain = data.size();
    while (bytes_remain && !result){
        package_size = (bytes_remain<KILOBYTE)?bytes_remain:KILOBYTE;
        bytes_sent = send(client_socket, &data[sent_total], package_size, 0);
        if (bytes_sent > 0){
            bytes_remain-= bytes_sent;
            sent_total+= bytes_sent;
        }
        else if(bytes_sent == SOCKET_ERROR){
            result = WSAGetLastError();
            break;
        }
    }
    return result;
}

在线程循环中:

while(CAMERA.Stream){
    OperationStartTime = GetTickCount();
    //RecvBuffer.resize(512);
    result = SendAll(CAMERA.Socket, CameraFrame);
    if(result != 0){
        cout << "error in send - " << result;
        CAMERA.Stream = false;
        break;
    }
    if (recv(CAMERA.Socket, &RecvBuffer, 1, 0) < 0){
        CAMERA.Stream = false;
        break;
    }  
    while(OperationStartTime + StreamRate > GetTickCount()){
        if (!CAMERA.Stream){break;}
        Sleep(1);
    }
}

有时我看到“发送错误 - 10053”(在localhost上测试)

服务器使用此功能接收所有数据:

int RecvAll(SOCKET &client_socket, string &data){
    data = "";
    int bytes_received = 0;
    int result = 0;
    char* recv_buffer;
    do {
        recv_buffer = (char*)malloc(KILOBYTE);
        bytes_received = recv(client_socket, recv_buffer, KILOBYTE, 0);
        if (bytes_received > 0){
            data.append(recv_buffer, bytes_received);
            if (bytes_received < KILOBYTE || data.size() >= 512*KILOBYTE){
                bytes_received = result = 0;}
        }
        else if(bytes_received == SOCKET_ERROR){
            data.clear();
            result = WSAGetLastError();
        }
        free(recv_buffer);
    }
    while (bytes_received > 0);
    return result;
}

服务器端没有错误。

SendAllRecvAll函数有什么问题以及如何实现稳定的数据传输?

PS:有时客户端停止,只有重新连接有帮助。但是如果要重新连接,服务器会再显示一个连接的套接字 - 这意味着CAMERA.Socket是阻塞的,我不明白为什么

1 个答案:

答案 0 :(得分:4)

客户端没有将数据大小发送到服务器,因此它知道要发送的每个帧实际读取的字节数。

它也没有处理服务器断开连接或正确处理StreamRate计算的情况。

尝试更像这样的东西:

客户端:

int SendAll(SOCKET client_socket, const void *data, int data_size)
{
    const char *data_ptr = (const char*) data;
    int bytes_sent;

    while (data_size > 0)
    {
        bytes_sent = send(client_socket, data__ptr, data_size, 0);
        if (bytes_sent == SOCKET_ERROR)
            return -1;

        data_ptr += bytes_sent;
        data_size -= bytes_sent;
    }

    return 1;
}

int SendAll(SOCKET client_socket, const string &data)
{
    ulong data_size = htonl(data.size());

    int result = SendAll(client_socket, &data_size, sizeof(data_size));
    if (result == 1)
        result = SendAll(client_socket, data.c_str(), data.size());

    return result;
}

...

int result;
char reply;

while (CAMERA.Stream)
{
    OperationStartTime = GetTickCount();

    result = SendAll(CAMERA.Socket, CameraFrame);
    if (result != 1)
    {
        cout << "error in send - " << WSAGetLastError();
        CAMERA.Stream = false;
        break;
    }

    result = recv(CAMERA.Socket, &reply, 1, 0);
    if (result <= 0)
    {
        if (result == 0)
            cout << "server disconnected";
        else
            cout << "error in read - " << WSAGetLastError();

        CAMERA.Stream = false;
        break;
    }  

    while (CAMERA.Stream && ((GetTickCount() - OperationStartTime) < StreamRate))
    {
        Sleep(1);
    }
}

服务器:

int RecvAll(SOCKET client_socket, void *data, int data_size)
{
    char *data_ptr = (char*) data;
    int bytes_recv;

    while (data_size > 0)
    {
        bytes_recv = recv(client_socket, data_ptr, data_size, 0);
        if (bytes_recv <= 0)
            return bytes_recv;

        data_ptr += bytes_sent;
        data_size -= bytes_sent;
    }

    return 1;
}

int RecvAll(SOCKET client_socket, string &data)
{
    ulong data_size;
    int result;

    data = "";

    result = RecvAll(client_socket, &data_size, sizeof(data_size));
    if (result == 1)
    {
        data_size = ntohl(data_size);
        if (data_size > 0)
        {
            data.resize(data_size);

            result = RecvAll(client_socket, &data[0], data_size);
            if (result != 1)
                data.clear();
        }
    }

    return result;
}

...

string data;
int result;
char reply;

while (true)
{
    result = RecvAll(socket, data);
    if (result != 1)
    {
        if (read == 0)
            cout << "client disconnected";
        else
            cout << "error in read - " << WSAGetLastError();

        break;
    }

    // process data as needed...

    reply = 1;
    if (send(socket, &reply, 1, 0) == SOCKET_ERROR)
    {
        cout << "error in send - " << WSAGetLastError();
        break;
    }
}