0
votes
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 am able to receive data from the client via the recvfrom api but later I have to send the response back to the client via sendto api within the XcpApp_IpTransmit( uint16 XcpPort, Xcp_StatePtr8 pBytes, uint16 numBytes ); (This is the api supported in my project for transmitting the data). Client is a tool for sending the data to the specified port and ip address. Can I use again struct sockaddr_in client; in the Transmit api ?? could some one help me ??

2

2 Answers

0
votes

struct sockaddr_in client; is you used in transmit API which is wrong where it is initialized?

So you must used initilized socket structure. from your above code you can received successfuly data from client but not able to send because your client structure in transmit function is NULL nothing initilized so where to go?

You can do something like this

rc=recvfrom(acceptSocket,buf, sizeof(buf), 0, (struct sockaddr*) &client, &len);

sendto(acceptSocket,buf,rc,0,(struct sockaddr *)&client,sizeof(client));

Or pass the client structure to the your transmit function as follows

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

This shall work. When you are working with SOCK_DGRAM, you can always send data back, using the received address (and it's size, in general case). Exceptions, of course, include cases, when the peer socket become unavailable.

Alternatively, if you have only one client, you can use connect to set the default remote peer address and send will use it:

sockaddr_in addr;
socklen_t len;

len = sizeof(addr);
x = recvfrom(socket,buf, sizeof(buf), 0, (struct sockaddr*) &addr, &len);
connect(socket, (struct sockaddr*)addr, len);
...
send(socket, buf, bufsize, 0);
send(socket, buf, bufsize, 0);
send(socket, buf, bufsize, 0);

One comment, though. You are using AF_INET and your code will work correctly. But you can make it compatible with other protocols as well. For that:

sockadd_storage addr;
socklen_t len;

len = sizeof(addr);
x = recvfrom(socket,buf, sizeof(buf), 0, (struct sockaddr*) &addr, &len);
...
sendto(socket,buf,bufsize,0,(struct sockaddr*)addr, len);

This type of code will work with any datagram protocol including AF_LOCAL and AF_INET6.