Send data to Socket using Aio command

Hello All,

i written program to send data asynchronously to socket using aio_write command and read the data using aio_read. Read data shows empty. i read the status and error of both operations (aio_read and aio_write) shows OK. i dont know what is happening?

Basic i have a doubt whether aysnchronous i/o operations to socket is possible in QNX?

Note: i used the same program to Aysnch write and read to a file. it is working(i can write and read). in that program i updated the File descriptor with Socket FD, it was not working.

Please help.

Can you post your sample code.

The fact it works with a file and not over a socket makes me think your doing something wrong with the way your opening your sockets.

Tim

Hi Tim,

Thanks for showing interest.

here is my code:
"sorry for complete code "

[code]char buffer[] = { “A text record to be written” },bufferread[100];
#define WAIT { while (!aio_flg); aio_flg = 0; }

static void aio_CompletionRoutine()
{
aio_flg = 1;
printf(“Triggered Aio operation completed\n”);
fflush (stdout);
}

int main( void )
{
int FD_Socket,FD_File;
int size_written,size_read;

//------------------create Socket FD -------------------------//
FD_Socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (FD_Socket == -1) {
printf(“cannot create socket %d\n”,FD_Socket);
fflush (stdout);
exit(EXIT_FAILURE);
}
else
{
printf(“Opening socket successful \n”);
fflush (stdout);
}
/* Zero out socket address /
memset(&SockAddress, 0, sizeof SockAddress);
/
The address is IPv4 /
SockAddress.sin_family = AF_INET;
/
IPv4 adresses is a uint32_t, convert a string representation of the octets to the appropriate value /
SockAddress.sin_addr.s_addr = inet_addr(“127.0.0.1”);
/
sockets are unsigned shorts, htons(x) ensures x is in network byte order, set the port to 7654 */
SockAddress.sin_port = htons(7654);

/* bind: When a socket is created with socket(), it exists in a namespace (address family)
 * but has no name assigned to it. The bind() function assigns a name to that unnamed socket. */
if (bind(FD_Socket, (struct sockaddr *)&SockAddress, sizeof SockAddress) == -1)
{
    perror("error bind failed\n");
    close(FD_Socket);
    exit(EXIT_FAILURE);
}
else
{
   printf("Binding socket successful\n");
   fflush (stdout);
}

//--------------------create File FD--------------------//
FD_File = creat( "myfile.dat", S_IRUSR | S_IWUSR );


//-------------------- Data write Operation--------------------//
my_aio.aio_fildes = FD_File; /* Assign either Socket or File FD */
my_aio.aio_nbytes = sizeof( buffer );
my_aio.aio_buf = &buffer;
my_aio.aio_sigevent.sigev_notify          = SIGEV_THREAD;
my_aio.aio_sigevent.sigev_notify_function = aio_CompletionRoutine;
size_written = aio_write(&my_aio); //Asynchronous Write Operation - File
if( size_written == -1 ) //Asynchronous Write Operation
{
    perror( "Error writing myfile.dat" );
    return EXIT_FAILURE;
}
else
{
    printf("Data sent sucessfully -- byte sent = %d\n",sizeof( buffer ));
    fflush (stdout);
    WAIT; // Asynchronous Write Operation - File
}

//-------------------- Data read Operation --------------------//
FD_File = open( “myfile.dat”, O_RDONLY );

my_aio.aio_fildes = FD_File; /* Assign either Socket or File FD */
my_aio.aio_nbytes = sizeof( buffer );
my_aio.aio_buf = &bufferread;
my_aio.aio_sigevent.sigev_notify          = SIGEV_THREAD;
my_aio.aio_sigevent.sigev_notify_function = aio_CompletionRoutine;
size_read = aio_read(&my_aio); // Asynchronous read operation
if( size_read == -1 ) {
    perror( "Error reading myfile.dat" );
    return EXIT_FAILURE;
}
else
{
    WAIT; // Asynchronous read operation
    printf("Data read sucessfully -- %s\n",&bufferread);
    fflush (stdout);
}

/* close the file  */
close( FD_Socket );
close( FD_File );

return EXIT_SUCCESS;

}[/code]

i can able to write and read if i assign aio_flides with FD_File. But when i assign aio_flides with FD_Socket. Data read shows empty.

Sen

Sen,

Is that really your complete code example?

I don’t see the variable definitions for aio_flg, SockAddress etc. I assume those are global variables (or in a .h file of yours someplace) that are ‘int’ and ‘struct sockaddr_in’.

Here’s some things I noticed in a brief glance:

  1. FD_Socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    Shouldn’t that be AF_INET and not PF_INET. Never seen PF_INET before. Also most people set the last argument to 0, not IPPROTO_UDP
  2. SockAddress.sin_addr.s_addr = inet_addr(“127.0.0.1”);
    Why are you trying to bind to the local interface adaptor (do you not have a network card/address)? Normally this line is just
    SockAddress.sin_addr.s_addr = INADDR_ANY; // Auto fill with my IP
    This may be the problem.
  3. if (bind(FD_Socket, (struct sockaddr *)&SockAddress, sizeof SockAddress) == -1)
    How does this line compile? Sizeof is a function so it should have brackets like so:
    if (bind(FD_Socket, (struct sockaddr *)&SockAddress, sizeof (SockAddress)) == -1)

Can you try fixing the above and see if that works for you. If not please post again the code with all the variable definitions so I can copy and try here on my machine.

One last thing that may be the most important of all. You are trying to use UDP sockets. They are themselves asynchronous and connection-less. I am not sure how aio_write() is going to be able to send to a specific IP address/port (note that setting the address in SockAddress is not the address you want to send to when using UDP sockets) because there is no way to tell it where to send (ie what IP address and port).

Tim

P.S. A google search of the aio_() functions under Linux says that they mostly aren’t supported for sockets. That’s likely the case for QNX too. If you are planning to use UDP sockets you don’t need aio_() anyway since as I said they are asynchronous by nature.

Hi Tim,

i tried with your inputs, still not working.

i referred en.wikipedia.org/wiki/Berkeley_sockets for my programming.

Here is my updated code: (previous post i thought definitions part will be not interest. so i didnt include)

[code]#include <stdio.h>
#include <pthread.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/neutrino.h>
#include <sys/iofunc.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <aio.h> // Asynchronus io libary

/* Global variables */
int SocketFD,FileFD;
struct sockaddr_in SockAddress;
int aio_flg;
struct aiocb my_aio;

char buffer[] = { “A text record to be written” },bufferread[100];
#define WAIT { while (!aio_flg); aio_flg = 0; }

static void aio_CompletionRoutine()
{
aio_flg = 1;
printf(“Triggered Aio operation completed\n”);
fflush (stdout);
}

int main( void )
{
int FD_Socket,FD_File;
int size_written,size_read;

//------------------create Socket FD -------------------------//
FD_Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (FD_Socket == -1) {
printf(“cannot create socket %d\n”,FD_Socket);
fflush (stdout);
exit(EXIT_FAILURE);
}
else
{
printf(“Opening socket successful \n”);
fflush (stdout);
}
/* Zero out socket address /
memset(&SockAddress, 0, sizeof SockAddress);
/
The address is IPv4 /
SockAddress.sin_family = AF_INET;
/
IPv4 adresses is a uint32_t, convert a string representation of the octets to the appropriate value /
SockAddress.sin_addr.s_addr = inet_addr(“127.0.0.1”);
/
sockets are unsigned shorts, htons(x) ensures x is in network byte order, set the port to 7654 */
SockAddress.sin_port = htons(7654);

/* bind: When a socket is created with socket(), it exists in a namespace (address family)
 * but has no name assigned to it. The bind() function assigns a name to that unnamed socket. */
if (bind(FD_Socket, (struct sockaddr *)&SockAddress, sizeof(SockAddress)) == -1)
{
    perror("error bind failed\n");
    close(FD_Socket);
    exit(EXIT_FAILURE);
}
else
{
   printf("Binding socket successful\n");
   fflush (stdout);
}

//--------------------create File FD--------------------//
FD_File = creat( "myfile.dat", S_IRUSR | S_IWUSR );


//-------------------- Data write Operation--------------------//
my_aio.aio_fildes = FD_Socket; /* Assign either Socket or File FD */
my_aio.aio_nbytes = sizeof( buffer );
my_aio.aio_buf = &buffer;
my_aio.aio_sigevent.sigev_notify          = SIGEV_THREAD;
my_aio.aio_sigevent.sigev_notify_function = aio_CompletionRoutine;
size_written = aio_write(&my_aio); //Asynchronous Write Operation - File
if( size_written == -1 ) //Asynchronous Write Operation
{
    perror( "Error writing myfile.dat" );
    return EXIT_FAILURE;
}
else
{
    printf("Data sent sucessfully -- byte sent = %d\n",sizeof( buffer ));
    fflush (stdout);
    WAIT; // Asynchronous Write Operation - File
}

//-------------------- Data read Operation --------------------//
FD_File = open( “myfile.dat”, O_RDONLY );

my_aio.aio_fildes = FD_Socket; /* Assign either Socket or File FD */
my_aio.aio_nbytes = sizeof( buffer );
my_aio.aio_buf = &bufferread;
my_aio.aio_sigevent.sigev_notify          = SIGEV_THREAD;
my_aio.aio_sigevent.sigev_notify_function = aio_CompletionRoutine;
size_read = aio_read(&my_aio); // Asynchronous read operation
if( size_read == -1 ) {
    perror( "Error reading myfile.dat" );
    return EXIT_FAILURE;
}
else
{
    WAIT; // Asynchronous read operation
    printf("Data read sucessfully -- %s\n",&bufferread);
    fflush (stdout);
}

/* close the file  */
close( FD_Socket );
close( FD_File );

return EXIT_SUCCESS;

}[/code]
Hopefully it will compile for u as well.

Point 1 and 3 are working for me even with my previous command. anyhow i updated with your input.
Point 2 - i want to test it with loop back ip. Send and read through same ip. (note: i even tried with your command “INADDR_ANY”, it doesnt work)

Regarding UDP, yes data transmission is connectionless between ports. But Aio target how you send data to sockets. My thought still asynchronously can send data to sockets with UDP protocol.

Regarding your P.S: yes i found the same. But there are no concrete answers whether it will support or not. i want to ensure whether socket can be accessed asynchronously in QNX or not. Do you know how/where to confirm that?

Thanks

Sen

Sen,

I’ll try your code shortly and let you know what I find. I suspect that the data is not being sent over the socket because there is no IP address to send to (You may be binding to 127.0.0.1 but you aren’t sending there or any other address as far as I can see).

As for asynchronous socket in QNX, yes, you can do that with both TCP and UDP sockets. You need to use threads (ie you need a thread that will wake up when data arrives from the socket and process that data) and set the socket option to async mode. That’s pretty much the only way we use sockets.

Tim

Sen,

I get this error when trying to compile in 6.32 (GCC 2.95.3 and also in 3.3.5)

test.cpp: In function int main()': test.cpp:87: assignment to void ()(sigval)’ from void (*)()' test.cpp:108: assignment to void ()(sigval)’ from `void (*)()’
cc: /usr/qnx630/host/qnx6/x86/usr/lib/gcc-lib/ntox86/2.95.3/cc1plus error 33

These are the lines it complains about
my_aio.aio_sigevent.sigev_notify_function = aio_CompletionRoutine;

I tried to figure out how what kind of casting it wants but I gave up after 5 minutes because I am too busy. If you can figure out the casting I’ll give it another try.

Otherwise you might try running tcpdump in another terminal and see if the send command ever actually puts out any packet. I suspect it does not because there is no send address.

Tim

Thanks Tim

i understood the error.

My thought about bind command was wrong. i will check for send options and try.

Thanks again for detailed explanation.

Sen