簡體   English   中英

有關數據包和緩沖區大小的TCP套接字編程

[英]TCP socket programming regarding the packet and buffer size

我知道TCP中沒有數據包的概念,因為它是一個流套接字,例如,如果我有一個2000字節的數據包,例如2000'a',而我的默認緩沖區大小是1024,則應該發送兩次收到兩次?

因此對於send()函數,

iResult = send(s, sendbuf, packet_size, 0);

對於第二個參數,我應該輸入什么? 發送緩沖區字符指針(分配了1024個字節)還是數據包字符指針(分配了2000個字節),它將自動為我處理?

對於recv()阻止函數,我應該將緩沖字符指針指向第二個參數還是數據包一個?

對於標題,我的朋友建議我添加4個字節的標題以存儲數據包信息,例如。 數據包的序列號和大小,如何實現? 謝謝

@喬吉,謝謝! 我也想問一下,如果我不執行部分寫操作,而while循環中的發送速率非常快(無睡眠),那么服務器端會出現錯誤/丟失嗎? 對於recv()

SOCKET newsfd;
bind(s, (struct sockaddr *)ReceiverSocket, sizeof(struct sockaddr_in));
if (strcmp(protocol, "tcp") == 0 || strcmp(protocol, "TCP") == 0){
    listen(s, 1);
    newsfd = accept(s, 0, 0);
}

//*** Create Update Display Thread
std::thread th(Function_packet_transmission_display, update_interval, (char*) "recv");

//*** Receive Data//*** Set Jitter
long time_old = 0, time_new = 0, time_start = 0;
long float jitter_new = 0, jitter_old = 0;
long long temp_accubyte = 0, temp_pktnum = 0; //testing
char *recvbuf = new char[buffer_size];
long long next_seq_num = 1; int retVal;
do{

    if (strcmp(protocol, "tcp") == 0 || strcmp(protocol, "TCP") == 0){
        retVal = recv(newsfd, recvbuf, packet_size, 0);
        if ((retVal == SOCKET_ERROR) || (retVal == 0)){
            printf("\nreturn fail code:%i\n", WSAGetLastError());
            closesocket(s);
            WSACleanup();
            lck.lock();
            Ended = true;
            lck.unlock();
            return 0;
        }
    }
    else if (strcmp(protocol, "udp") == 0 || strcmp(protocol, "UDP") == 0){
        int fromlen = (int)sizeof(struct sockaddr_in);
        retVal = recvfrom(s, recvbuf, packet_size, 0, (struct sockaddr *)ReceiverSocket, &fromlen);
    }
    //testing
    temp_accubyte += retVal;
    temp_pktnum++;//TEST
    //printf("\racc: %lld %lld    -   ", temp_accubyte, temp_pktnum);
    //if (temp_pktnum==100000)            printf("\nReach 100000\n", temp_accubyte, temp_pktnum);

    if (timer == NULL){
        timer = new ES_FlashTimer();
    }

如果我有一個2000字節的數據包,說2000'a',

你不知道 您有一條2000字節的消息

我的默認緩沖區大小是1024

不太可能。 至少是8192,可能是數千K。

然后應該發送兩次

至少。

並收到兩次?

至少。

對於第二個參數,我應該輸入什么?

您要發送的消息的大小:在這種情況下,為2000。

發送緩沖區字符指針並分配了1024個字節

沒有。

還是具有2000個字節的數據包字符指針,它將自動為我處理?

是。

對於recv()阻止函數,我應該將緩沖字符指針指向第二個參數還是數據包一個?

我無法說清楚這一點,但您應該將其盡可能多地放入緩沖區並循環,直到獲得完整的消息為止。

對於標題,我的朋友建議我添加4個字節的標題以存儲數據包信息,例如。 包的序號和大小,如何實現!

您實際上並不需要序列號,但是消息大小是個好主意。 只需將其粘貼在消息的前面即可。 不清楚這里的問題。

您將需要像此處的 sendall,並且(可能)需要編寫類似的receivall 這是sendall (稍作修改):

#include <sys/types.h>
#include <sys/socket.h>

int sendall(int s, char *buf, int *len)
{
    int total = 0;        // how many bytes we've sent
    int bytesleft = *len; // how many we have left to send
    int n = -1;

    while(total < *len) {
        n = send(s, buf+total, bytesleft, 0);
        if (n <= 0) {  break; }
        total += n;
        bytesleft -= n;
    }

    *len = total;  

    return (n<=0)?-1:0; // return -1 on failure, 0 on success
} 

您可以在這里閱讀如何處理消息框架 ,這是您所需要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM