<alarm call> systemmessage with threads and socket

<alarm call> systemmessage with threads and socket

Post by Fischbacher Marku » Thu, 22 Mar 2001 21:41:17



hi all!

i`ve got a problem with sockets and threads.
a little program should write character to and read character from a socket.
it listen easy...but...read below...

here a short description of the program:

the program starts a listener thread.
another thread connects to this listener.
as result a server thread is created.
the client sends a few characters to the server which shows them in the
commandline.
for every call to select (poll) function a point is shown in the
commandline.
this would work until a systemmessage <alarm call> appears and the program
quit.
if the characters where sent fast, that means the call to usleep (in
function sendToServer()) is removed, the program run.
when usleep is in the code, the program quit after one pass.
the usleep function is marked in the sourcecode.

i have no idea why the systemmessage is sent.
maybe there is a wrong compiler flag or an wrong header file?
can anybody help me?

ive allready tried to implement the pthread_sigmask() ignoring SIGALRM. it
wont work!

thx for help!

markus

my system: x386 processor, unixware 7.1.1, gnu compiler 2.95.2pl1

ps: sourcecode, program output and makefile are shown below.

pps: by the way... why the function <select> won't work? instead i take the
<poll> function.

**********************************************************
here the sample code, alas it cant be shorter than posted
**********************************************************

#include <iostream>
#include <iomanip>
#include <string>

#include <netinet/in.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <sys/termio.h>
#include <sys/filio.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <stropts.h>

#include <pthread.h>
#include <semaphore.h>
#include <errno.h>
#include <unistd.h>

const char *pszHostName = "pcname";
int nPort = 5599;

static void ExitError (const char *pszText, int nError = 0)
{
 int nErr = nError ? nError : errno;
 std::cout << pszText << ' ' << nErr << std::endl;
 exit (nErr);

}

int selectWrite (int hSocket)
{
 struct pollfd poll_pirs;
 poll_pirs.fd = hSocket;
 poll_pirs.events = POLLWRNORM;
 poll_pirs.revents = 0;

 return poll (&poll_pirs, 1, 1000);

// wont work
/* fd_set fd;
 FD_ZERO (&fd);
 FD_SET (hSocket, &fd);
 timeval tv = { 1, 0 };  // 1 sec

 return select (1, NULL, &fd, NULL, &tv);
*/

}

int selectRead (int hSocket, long nSec)
{
 struct pollfd poll_pirs;
 poll_pirs.fd = hSocket;
 poll_pirs.events = POLLRDNORM;
 poll_pirs.revents = 0;

 return poll (&poll_pirs, 1, 1000 * nSec); // millisec

// wont work
/* fd_set fd;
 FD_ZERO(&fd);
 FD_SET(hSocket, &fd);
 timeval tv = { nSec, 0};

 return select ( 1, &fd, NULL, NULL, &tv);
*/

}

void startListenerThread (void);
void startServerThread (int hSock);
void startClientThread (void);

////////////////////////////////////////////////////////////////////////////
////
// ListenerThread
//
void* ListenerThread (void *pv)
{
 std::cout << "Listener started" << std::endl;

 struct sockaddr_in adr;
 memset (&adr, 0, sizeof (adr));
 adr.sin_family = AF_INET;
 adr.sin_port = htons (nPort);

 // socket()
 int hSocket = socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
 if (hSocket < 0)
  ExitError ("Listener:socket()");

 // setsockopt()
 int optval = 1;

 if (setsockopt (hSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&optval,
sizeof(int)) < 0)
  ExitError ("Listener:setsockopt(SO_KEEPALIVE)");

 if (setsockopt (hSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&optval,
sizeof(int)) < 0)
  ExitError ("Listener:setsockopt(SO_REUSEADDR)");

 // bind()
 if (bind (hSocket, (struct sockaddr*)&adr, sizeof(sockaddr)) < 0)
  ExitError("Listener:bind()");

 // listen()
 if (listen (hSocket, 128) < 0)
  ExitError ("Listener:listen()");

 while (1)
 {
  // select()
  int nSel = selectRead (hSocket, 5);
  if (nSel < 0)
   ExitError ("Listener:select()");

  if (nSel > 0)
  {
   // accept() -> start ServerThread
   size_t nLengthAddr = sizeof(sockaddr);
   struct sockaddr dummy;
   int hNewSock = accept (hSocket, &dummy, &nLengthAddr);
   if (hNewSock < 0)
    ExitError("Listener:accept()");

   startServerThread (hNewSock);
  }
 }

 return 0;

}

////////////////////////////////////////////////////////////////////////////
////
// ServerThread
//
// sends back the recieved string
//
void* ServerThread (void *pvhSocket)
{
 std::cout << "Server started" << std::endl;

 int hSocket = *(int*)pvhSocket;
 delete (int*)pvhSocket;

 std::string strRecv;
 while (1)
 {
  std::cout << '.' << std::flush;

  // select()
  int nSel = selectRead (hSocket, 1);
  if (nSel < 0)
   ExitError ("server:select()");

  if (nSel > 0)
  { // recv()
   char c;
   int nRead = recv (hSocket, &c, 1, 0);
   if (nRead != 1)
    ExitError ("server:recv()");

   strRecv += c;
  }
  else
  {
   // nothing recieved -> answer
   if (strRecv.size ())
   {
    std::cout << std::endl;

    // send()
    selectWrite (hSocket);
    if (send (hSocket, strRecv.c_str (), strRecv.size (), 0) < 0)
     ExitError ("server:send()");

    strRecv = "";
   }
   else
    usleep (100000); // 100 ms
  }
 }
 return 0;

}

////////////////////////////////////////////////////////////////////////////
////
// ClientThread
//
// sends a string to server and waits for answer
//
static void sendToServer (int hSocket)
{
 char pszToSend [] = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
 int nToSend = strlen (pszToSend);

 std::cout << "\nClient sleep()" << std::endl;

// *** usleep ***
// here is the usleep described above
// if this usleep is not in the code, the program work!
 usleep (500000); // 500 ms

 std::cout << "\nClient select() for writing" << std::endl;
 if (selectWrite (hSocket) <= 0)
  ExitError ("Client:select ()");

 std::cout << "\nClient will send" << std::endl;
 if (send (hSocket, pszToSend, nToSend, 0) != nToSend)
  ExitError ("Client:send()");

 std::cout << "\nClient has sent " << pszToSend << std::endl;

}

void* ClientThread (void *pv)
{
 std::cout << "Client started" << std::endl;

 // socket()
 int hSocket = socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
 if (hSocket < 0)
  ExitError ("Client:socket()");

 // connect()
 struct hostent *pHost;
 pHost = gethostbyname (pszHostName);
 if(!pHost)
  ExitError ("Client:gethostbyname()");

 struct sockaddr_in addr;

 memcpy (&addr.sin_addr, pHost->h_addr, pHost->h_length);
 addr.sin_family = pHost->h_addrtype;
 addr.sin_port = htons (nPort);

 if (connect (hSocket, (struct sockaddr *) &addr, sizeof(addr)) < 0)
  ExitError ("Client:connect()");

 sendToServer (hSocket);

 std::string strRecv;
 while (1)
 {
  // select(), recv()
  int nSel = selectRead (hSocket, 1);
  if (nSel < 0)
   ExitError ("Client:select()");

  if (nSel > 0)
  {
   char c;
   int nRead = recv (hSocket, &c, 1, 0);
   if (nRead != 1)
    ExitError ("Client:recv()");

   strRecv += c;
  }
  else
   if (strRecv.size ())
   {
    std::cout << "\nClient recieved " << strRecv << std::endl;
    sendToServer (hSocket);
    strRecv = "";
   }
   else
    usleep (100000); // 100 ms
 }

 return 0;

}

void startListenerThread (void)
{
 pthread_t  hThread;
 int nError = pthread_create (&hThread, NULL, ListenerThread, 0);
 if (nError)
  ExitError ("pthread_create()", nError);

}

void startServerThread (int hSock)
{
 pthread_t  hThread;
 int nError = pthread_create(&hThread, NULL, ServerThread, new int (hSock));
 if (nError)
  ExitError ("pthread_create()", nError);

}

void startClientThread (void)
{
 pthread_t  hThread;
 int nError = pthread_create(&hThread, NULL, ClientThread, 0);
 if (nError)
  ExitError ("pthread_create()", nError);

}

int main (int argc, char* argv[])
{
 startListenerThread ();
 sleep (1);    // 1 sec
 startClientThread ();

 while (1)
  sleep (1);

 return 0;

}

*******************************************
this is the output the program will produce
*******************************************

Listener started
Client started

Client sleep()

Client select() for writing

Client will send

Client has sent ABCDEFGHIKLMNOPQRSTUVWXYZ
Server started
..........................
.
Client recieved ABCDEFGHIKLMNOPQRSTUVWXYZ

Client sleep()
.Alarm call

********************
heres the makefile:
********************

############################################################################
###############
CXX = g++
LDXX = g++

CXXFLAGS = -c -D_REENTRANT -g
COMPILE = $(CXX) $(CXXFLAGS)
############################################################################
###############

OBJECTS = AlarmCall.o
OUTPUT = alarmcall

LDXXFLAGS = -o

COMPILE = $(CXX) $(CXXFLAGS)
LINK = $(LDXX) $(LDXXFLAGS) $(OUTPUT) $(OBJECTS) -lthread -lsocket

# Linken
$(OUTPUT) : $(OBJECTS)
 $(LINK)

# Kompilieren
AlarmCall.o: AlarmCall.cpp
 $(COMPILE) AlarmCall.cpp

 
 
 

1. <><><> MOUNTING EXTENDED PARTITION <><><>

I have a 10 GB UDMA IDE drive formatted with Windows.  The first partition
is FAT32, and the second is NTFS.  I can successfully mount the first, but
not the second.  Any ideas?

Suse 7.2 on i86
the drive is mounted on /dev/hdc, and I CAN see hda1, but not hda2

2. Highscreen Scanner at AHA1502

3. Wanted: <><><> Unix Specialist <><><>

4. help cyclades 16Y setup

5. LILO help <><><><><><>

6. Help with Redhat 6.1 Install

7. <<<connect call in a child pthread...>>>

8. I've broken Netscape 4.03 - any suggestions?

9. >>> unclosed socket <<<

10. <Alt>+<key> = <Esc><key> ?

11. *{<><>}*Linux*Screen*Difficulties*{<><>}*

12. << <<anyone using dyn-html?>> >>

13. (<><>)*Linux*Screen*Difficulties*(<><>)