Recv function and send function in socket programming

1. The recv () function

The recv () function is used to receive messages in socket communication

#include <sys/types.h>

#include<sys/socket.h>

ssize_t  recv(int sockfd, void *buff,size_t nbytes,int flags);

sockfd: file descriptor;

buff: points to a buffer, used to store the received data

nbytes: specify the length of the buff

flags: generally set to 0

Return value: Fail, return less than 0; timeout or peer closes, return 0; success, return received data length

Explanation: Although the buffer buff length of the received message is nbytes, the data received each time is not necessarily nbytes, and nbytes is just the length of the container.

int receivefunc()
{
    //一般先接收一次报头,报头确认后再接着接收剩下的报文
    /*
    接收并确认是已知的报文头;
    */
    char buff[128] = {0};
    int length = N //N为已知的报文的长度字节数
    fd_set r_set;
    struct timeval w_time;
    w_time.tv_sec = 3;
    w_time.tv_usec = 0;
    FD_ZERO(&fd_recv);
    FD_SET(connfd,&r_set);
    while(1)
    {
        int ret = select(connfd+1,&fd_recv,(fd_set*)0,(fd_set*)0,&w_time);
        if(ret <0)
        {
            if((errno == EINTR)||(errno== EAGAIN))
                continue;
            printf("select error:%s\n",strerror(errno));
            return -1;
        }else if(ret == 0){
            printf("select timeout:%s\n",strerror(errno));
            return 0;
        }else
            break;
    }
    if(FD_ISSET(connfd,&r_set)
    {
        int irecv,iunrecv;
        iunrecv = length;
        while(iunrecv>0)
        {
            irecv = recv(concfd,buff,iunrecv,0)
            if(irecv==0)
            {
                 printf("recv error:%s",strerror(errno));
                 return -1;
            }
            if(irecv<0)            
            {
                if(errno == EINTR ||(errno == EAGAIN)||errno == EWOULDBLOCK)
                    continue;

                 printf("recv error:%s",strerror(errno));
                 return -1;
            }
            iunrecv -= irecv;
            buff += irecv;
        }
    }
}

 Summary: The recev () function may not be able to receive the data to be sent at once, so it must be received in a loop;

2. The send () function

#include <sys/types.h>

#include<sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);

sockfd: sender socket descriptor

buf: point to the data to be sent // char ch [N]; array

nbytes: the actual number of bytes of data to be sent /// may not be sent every time

flags: generally set to 0

Return value: Failed, the return value is less than 0; timeout or the other end actively closes, returns 0; success, returns the length of the data sent.

The only difference between send and write is the existence of the last parameter flags. When flags is 0, send and wirte are equivalent.

After the send function is called: Compare the length of nbytes and socket sockfd send buffer blength:

1) nbytes> blength, the function returns SOCKET_ERROR;

2)nbytes<=blength,

     a) send first check whether the protocol is sending the data in the send buffer of s, if it is, wait for the protocol to send the data;

      b) If the protocol has not started sending data in s's send buffer or s's send buffer has no data, then send compares the remaining space of s' send buffer with nbytes

             i) If nbytes is greater than the remaining space, send will wait for the protocol to send the data in the send buffer of s,

             ii) If nbytes is less than the size of the remaining space send, only copy the data in buf to the remaining space (note that send does not send the data in the send buffer of s to the other end of the connection, but the protocol, send only Is to copy the data in buf to the remaining space of s's sending buffer)

            If the send function copies the data successfully, it returns the actual number of bytes copied. If send has an error when copying the data, then send returns SOCKET_ERROR; if send is waiting for the protocol to transmit data, the network is disconnected, then the send function returns SOCKET_ERROR .

Summary: The case of nbytes <= blength has said so much, in fact, regardless of the process, as long as there is no error in copy, it can be sent normally at this time.

int sendfunc()
{
    char buff[128] = {0};
    memcpy(buff....);//buff中存储的要send的数据
    int length = strlen(buff);//buff中的数据长度

    fd_set w_set;
    struct timeval w_time;
    w_time.tv_sec = 3;
    w_time.tv_usec = 0;
    FD_ZERO(&fd_send);
    FD_SET(connfd,&w_set);
    while(1)
    {
        int ret = select(connfd+1,(fd_set*)0,&w_set,(fd_set*)0,&w_time);
        if(ret <0)
        {
            if((errno == EINTR)||(errno== EAGAIN))
                continue;
            printf("select error:%s\n",strerror(errno));
            return -1;
        }else if(ret == 0){
            printf("select timeout:%s\n",strerror(errno));
            return 0;
        }else
            break;
    }
    if(FD_ISSET(connfd,&w_set)
    {
        int isend,iunsend;
        iunsend = length;
        while(iunsend>0)
        {
            isend = send(concfd,buff,iunsend,0)
            if(isend<=0)            
            {
                 printf("send error:%s",strerror(errno));
                 return -1;
            }
            iunsend -= isend;
            buff += isend;
        }
    }
}

Summary: The send () function may not be able to send the data to be sent at once, so it needs to be sent in a loop;

int main()
{
    socket();
    connect();
    while(1)
    {
        receivefun();
        sendfun();
    }
}

 

Published 100 original articles · won 26 · 20,000+ views

Guess you like

Origin blog.csdn.net/modi000/article/details/105580382
Recommended