简体   繁体   中英

TCP socket programming regarding the packet and buffer size

I know that there is no packet concept in TCP as it is a stream socket, then for example, if i have a packet of 2000 bytes, say 2000 'a', and my default buffer size is 1024, then it is supposed to send twice and received twice?

so for the send() function,

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

for the second parameter, what should i put? a sending buffer character pointer with 1024 bytes mallocated or a packet character pointer with 2000 bytes and it will handle it for me automatically ?

and for the recv() blocking function, i should put the buffer character pointer to the second parameter or the packet one?

and for the header, my friend suggested me to add header of 4 bytes to store the packet information, eg. sequence number and size of packet, how can it be implemented ? thanks

@Giorgi, Thanks! and i also want to ask, if i dont do the partial writes handling and the send rate in the while loop is very faster (no sleep), so will there be error/lost in server side? for the 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();
    }

If i have a packet of 2000 bytes, say 2000 'a',

You don't. You have a message of 2000 bytes.

and my default buffer size is 1024

Unlikely. It will be at least 8192, possibly many thousands of K.

then it is supposed to send twice

At least.

and received twice?

At least.

for the second parameter, what should i put?

The size of the message you want to send: in this case, 2000.

sending buffer character pointer with 1024 bytes mallocated

No.

or a packet character pointer with 2000 bytes and it will handle it for me automatically ?

Yes.

and for the recv() blocking function, i should put the buffer character pointer to the second parameter or the packet one?

I can't make head or tail of this, but you should receive into a buffer as large as possible and loop until you have the entire message.

and for the header, my friend suggested me to add header of 4 bytes to store the packet information, eg. sequence number and size of packet, how can it be implemented!

You don't really need the sequence number, but a message size is a good idea. Just stick it in the front of the message. Unclear what the question is here.

You will need sendall like here , and you will (probably) need to write a similar receivall . Here is the sendall (slightly modified):

#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
} 

And you can read up here how to deal with message framing , which is what you need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM