简体   繁体   English

用于Linux的套接字程序中的recvfrom api

[英]recvfrom api in socket program for linux

int acceptSocket;
char buf[100];
long sentbytes;
socklen_t len;
int port = 18227;

int CreateSocket()
{
    long rc;
    struct sockaddr_in addr, client;

       // Socket creation for UDP
       acceptSocket=socket(AF_INET,SOCK_DGRAM,0);

       if(acceptSocket==-1)
       {
         printf("Failure: socket creation is failed, failure code\n");
         return 1;
       }
       else
       {
         printf("Socket started!\n");
       }

     memset(&addr, 0, sizeof(struct sockaddr_in));
     addr.sin_family=AF_INET;
     addr.sin_port=htons(port);
     addr.sin_addr.s_addr=htonl(INADDR_ANY);
     rc=bind(acceptSocket,(struct sockaddr*)&addr,sizeof(addr));

     if(rc== -1)
     {
       printf("Failure: listen, failure code:\n");
       return 1;
     }
     else
     {
       printf("Socket an port %d \n",port);
     }

     while(rc!=-1)
         {
         len =sizeof(client);
         rc=recvfrom(acceptSocket,buf, sizeof(buf), 0, (struct sockaddr*) &client, &len);
         if(rc==0)
         {
           printf("Server has no connection..\n");
           break;
         }
         if(rc==-1)
         {
             printf("something went wrong with data %s", strerror(errno));
           break;
         }

         XcpIp_RxCallback( (uint16) rc, (uint8*) buf, (uint16) port );

            makeTimer("First Timer", &firstTimerID, 2, 2);   //2ms
                makeTimer("Second Timer", &secondTimerID, 10, 10);    //10ms
                makeTimer("Third Timer", &thirdTimerID, 100, 100);  //100ms
          }

       close(acceptSocket);
       return 0;
     }

int main()
{
     Xcp_Initialize();
     CreateSocket();
     return 0;
}

//API for sending the data to the client.
void XcpApp_IpTransmit( uint16 XcpPort,  Xcp_StatePtr8 pBytes, uint16 numBytes )
{
    struct sockaddr_in client;

        if ((long)XcpPort==port){
                sentbytes = sendto(acceptSocket,(char*)pBytes,(long)numBytes,0, (struct sockaddr*)&client, sizeof(client));
        }
        XcpIp_TxCallback(port,(uint16)sentbytes);
}

I created a server side program for receiving data from the client and sending the response back to the client. 我创建了一个服务器端程序,用于从客户端接收数据并将响应发送回客户端。 I don't know where is the mistake in the above program, I am able to receive data from the client and the rc value is zer0 in that case. 我不知道上面程序中的错误在哪里,我能够从客户端接收数据,在这种情况下rc值为zer0。 Then I am checking the value of rc and it is coming out of the program. 然后,我正在检查rc的值,它从程序中出来。 later There is no response back to the client. 以后没有任何响应返回给客户端。 Client is a tool for sending the data to the specified port and ip address. 客户端是用于将数据发送到指定端口和IP地址的工具。

what could be the problem and why rc value is zero after the recvfrom api ?? 可能是什么问题,为什么在recvfrom api之后rc值为零? NOTE: Client will be keep on sending the data. 注意:客户端将继续发送数据。 Could anyone help me in this ? 有人可以帮我吗?

According to recvfrom man page 根据recvfrom手册页

Upon successful completion, recvfrom() shall return the length of the message in bytes. 成功完成后,recvfrom()将以字节为单位返回消息的长度。 If no messages are available to be received and the peer has performed an orderly shutdown, recvfrom() shall return 0. Otherwise, the function shall return -1 and set errno to indicate the error. 如果没有消息可供接收并且对等方已执行有序的关闭,则recvfrom()将返回0。否则,该函数将返回-1并设置errno以指示错误。

So i think in your case You get a return value of 0 for recvfrom() when the connection was closed by the other host (wether this disconnection was graceful or not doesn't matter) 因此,我认为在您的情况下,当连接被另一台主机关闭时, recvfrom()的返回值为0(此断开是否正常还是无关紧要)

Also i have updated your code please try it on your end 我也更新了您的代码,请尝试一下

#define BUFLEN 100  //Max length of buffer
#define PORT 18227   //The port on which to listen for incoming data

void die(char *s)
{
    perror(s);
exit(1);
}

int acceptSocket;
char buf[BUFLEN];
long sentbytes;

int CreateSocket()
{
    struct sockaddr_in si_me, si_other, si_other2;

    int s, i, slen = sizeof(si_other) , recv_len;

    //create a UDP socket
    if ((acceptSocket=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
    {
        die("socket");
    }

    // zero out the structure
    memset((char *) &si_me, 0, sizeof(si_me));

    si_me.sin_family = AF_INET;
    si_me.sin_port = htons(PORT);
    si_me.sin_addr.s_addr = htonl(INADDR_ANY);

    //bind socket to port
    if( bind(acceptSocket , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)
    {
        die("bind");
    }

    //keep listening for data
    while(1)
    {
        printf("Waiting for data...");
        fflush(stdout);

        //try to receive some data, this is a blocking call
        if ((recv_len = recvfrom(acceptSocket, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == -1)   // read datagram from server socket
        {
            die("recvfrom()");
        }

        //print details of the client/peer and the data received
        printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));         printf("Data: %s\n" , buf);

        XcpIp_RxCallback( (uint16) rc, (uint8*) buf, (uint16) port );

        makeTimer("First Timer", &firstTimerID, 2, 2);   //2ms
        makeTimer("Second Timer", &secondTimerID, 10, 10);    //10ms
        makeTimer("Third Timer", &thirdTimerID, 100, 100);  //100ms
    }

    close(s);
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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