Everyone,
I wrote a little program to test sockets with.
No matter what I try, I always get:
./testSocket_aio
listening
aio_read() failed with rc=-1 and errno=11
aio_read: Resource temporarily unavailable
aio_write() failed with rc=-1 and errno=11
aio_write failed: Resource temporarily unavailable
Segmentation fault
Can anyone tell me what I am doing wrong here?
Thanks,
Jeff
------------------- code begins here ------------------------------
extern "C"
{
#include <linux/aio.h>
}
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
static const int PORT=5809;
static const char* SERVERHOST="localhost";
static const unsigned int SLEEP_USECS=1;
static const size_t MAXMSG=512;
static int Test_Result=EXIT_SUCCESS;
void init_sockaddr (struct sockaddr_in *name, const char *hostname, unsigned
short int port)
{
struct hostent *hostinfo;
name->sin_family = AF_INET;
name->sin_port = htons (port);
hostinfo = gethostbyname (hostname);
if (NULL == hostinfo )
{
fprintf (stderr, "Unknown host %s.\n", hostname);
Test_Result=EXIT_FAILURE;
exit (EXIT_FAILURE);
}
name->sin_addr = *(struct in_addr *) hostinfo->h_addr;
}
int make_socket (unsigned short int port)
{
int sock;
struct sockaddr_in name;
/* Create the socket. */
sock = socket (PF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror ("socket");
Test_Result=EXIT_FAILURE;
exit (EXIT_FAILURE);
}
/* Give the socket a name. */
name.sin_family = AF_INET;
name.sin_port = htons (port);
name.sin_addr.s_addr = htonl (INADDR_ANY);
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
{
perror ("bind");
Test_Result=EXIT_FAILURE;
exit (EXIT_FAILURE);
}
return sock;
}
void write_to_server (int filedes)
{
static int writeCount=0;
static char msg[MAXMSG];
/* set up aio stuff */
struct aiocb aiocb_write;
aiocb_write.aio_fildes = filedes;
aiocb_write.aio_offset = 0;
aiocb_write.aio_buf = msg;
aiocb_write.aio_reqprio = 0;
aiocb_write.aio_sigevent.sigev_notify = SIGEV_NONE;
aiocb_write.aio_sigevent.sigev_value.sival_ptr = (void *) &aiocb_write;
int rc(0),rc1(0),rc2(0);
struct aiocb* list_aiocb[1];
int write_inprogress(0);
for (writeCount=0; writeCount <= 100; writeCount++)
{
usleep(SLEEP_USECS);
if ( 100 == writeCount )
sprintf(msg,"QUIT");
else
sprintf(msg,"%3d: Hello from client",writeCount);
aiocb_write.aio_nbytes = strlen(msg)+1;
// now write it using aio
rc = aio_write(&aiocb_write);
if ( 0 != rc )
{
fprintf(stderr,"aio_write() failed with rc=%d and
errno=%d\n",rc,errno);
perror("aio_write failed");
Test_Result=EXIT_FAILURE;
exit (EXIT_FAILURE);
}
// suspend until the write is finished
list_aiocb[0] = &aiocb_write;
write_inprogress=1;
rc = aio_suspend(list_aiocb,1,NULL);
if ( -1 == rc )
{
perror("aio_suspend");
Test_Result=EXIT_FAILURE;
exit (EXIT_FAILURE);
}
if ( 0 != rc )
{
perror("unknown aio_suspend error");
Test_Result=EXIT_FAILURE;
exit (EXIT_FAILURE);
}
// an async i/o event occurred, since we dropped out of the
aio_suspend() without error
while ( 1 == write_inprogress )
{
rc1 = aio_error(list_aiocb[0]);
if ( EINPROGRESS == rc1 )
{
// write still in progress
}
else
{
rc2 = aio_return(list_aiocb[0]);
if ( -1 == rc2 )
{
perror("aio_return for write");
Test_Result=EXIT_FAILURE;
exit (EXIT_FAILURE);
}
if ( ( 0 == rc1 ) || ( 0 == rc2 ) )
{
// write finished successfully
fprintf (stderr, "Client: tx message:
`%s'\n", msg);
write_inprogress=0;
list_aiocb[0] = NULL;
}
else
{
perror("unknown error in aio_return for
write");
Test_Result=EXIT_FAILURE;
exit (EXIT_FAILURE);
}
}
}
}
}
int runClient(void)
{
int sock;
struct sockaddr_in servername;
/* Create the socket. */
sock = socket (PF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror ("socket (client)");
Test_Result=EXIT_FAILURE;
exit (EXIT_FAILURE);
}
/* Connect to the server. */
init_sockaddr (&servername, SERVERHOST, PORT);
if (0 > connect (sock, (struct sockaddr *) &servername, sizeof
(servername)))
{
perror ("connect (client)");
Test_Result=EXIT_FAILURE;
exit (EXIT_FAILURE);
}
/* Send data to the server. */
write_to_server (sock);
close (sock);
return EXIT_SUCCESS;
}
int runServer(void)
{
int sock,connectedSocket;
struct sockaddr_in clientname;
size_t size;
/* Create the socket and set it up to accept connections. */
sock = make_socket(PORT);
if (listen(sock, 1) < 0)
{
perror ("listen");
Test_Result=EXIT_FAILURE;
return EXIT_FAILURE;
}
else
printf("listening\n");
size = sizeof (clientname);
connectedSocket = accept(sock, (struct sockaddr *) &clientname, &size);
if ( -1 == connectedSocket )
{
perror ("accept");
Test_Result=EXIT_FAILURE;
return EXIT_FAILURE;
}
static int readCount=0;
char* msg = new char[MAXMSG];
/* set up aio stuff */
struct aiocb aiocb_read;
aiocb_read.aio_fildes = connectedSocket;
aiocb_read.aio_offset = 0;
aiocb_read.aio_buf = msg;
aiocb_read.aio_nbytes = MAXMSG;
aiocb_read.aio_reqprio = 0;
aiocb_read.aio_sigevent.sigev_notify = SIGEV_NONE;
aiocb_read.aio_sigevent.sigev_value.sival_ptr = (void *) &aiocb_read;
int rc(0),rc1(0),rc2(0);
struct aiocb* list_aiocb[1];
int read_inprogress(0);
int quitit(0);
while ( 0 == quitit )
{
// read the socket
rc = aio_read(&aiocb_read);
if ( 0 != rc )
{
fprintf(stderr,"aio_read() failed with rc=%d and
errno=%d\n",rc,errno);
perror("aio_read");
Test_Result=EXIT_FAILURE;
return EXIT_FAILURE;
}
// an async i/o event occurred, since we dropped out of the
aio_suspend() without error
while ( 1 == read_inprogress )
{
// suspend until the read is finished
list_aiocb[0] = &aiocb_read;
read_inprogress=1;
rc = aio_suspend(list_aiocb,1,NULL);
if ( -1 == rc )
{
perror("aio_suspend");
Test_Result=EXIT_FAILURE;
exit (EXIT_FAILURE);
}
if ( 0 != rc )
{
perror("unknown aio_suspend error");
Test_Result=EXIT_FAILURE;
exit (EXIT_FAILURE);
}
rc1 = aio_error(list_aiocb[0]);
if ( EINPROGRESS == rc1 )
{
// read still in progress
}
else
{
rc2 = aio_return(list_aiocb[0]);
if ( -1 == rc2 )
{
perror("aio_return for read");
Test_Result=EXIT_FAILURE;
exit (EXIT_FAILURE);
}
if ( ( 0 == rc1 ) || ( 0 == rc2 ) )
{
// read finished successfully
fprintf (stderr, "Server: %3d : rcv
message: `%s'\n", readCount++,msg);
read_inprogress=0;
list_aiocb[0] = NULL;
if ( 0 == strcmp(msg,"QUIT") )
quitit=1;
}
else
{
perror("unknown error in aio_return for
read");
Test_Result=EXIT_FAILURE;
exit (EXIT_FAILURE);
}
}
}
}
close(connectedSocket);
close(sock);
fprintf(stderr,"runServer() is returning\n");
return EXIT_SUCCESS;
}
void spawn(void)
{
switch( fork() )
{
case -1:
perror("fork() failed");
Test_Result=EXIT_FAILURE;
break;
case 0:
sleep(1);
runClient();
exit(Test_Result);
default:
runServer();
int status;
if ( -1 == wait(&status) )
perror("wait() failed");
break;
}
}
int main()
{
spawn();
if ( EXIT_FAILURE == Test_Result )
fprintf(stderr,"test failed\n");
return Test_Result;
}
------------------- code ends here ------------------------------
|