[an error occurred while processing this directive]

HP OpenVMS Systems

ask the wizard
Content starts here

DECthreads and sockets on OpenVMS VAX?

» close window

The Question is:

 
I want to create a multithreading socket server and a client, but when i
create two therads per client for reading and writing to the socket, the
reader-thread from the client blocks the server reader-thread. So what can i
do ?
 
here is the code (it's not a very good code, because, i'm a beginner):
 
Client:
 
/* Threads & Sockets Client  */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <types.h>
#include <socket.h>
#include <in.h>
#include <inet.h>
#include <netdb.h>
#include <string.h>
#include <unixio.h>#include <pthread.h>
 
#define port 2233
#define ipaddr "SCPV20"
 
int			connmtt,
		 	inadr;
char			nickname[12];
static char		msg[BUFSIZ],
			rmsg[BUFSIZ];
struct sockaddr_in	addr;
struct hostent		*host;
pthread_t		pread;
pthread_t		psend;
pthread_addr_t		status;
 
void * psend_tc(pthread_addr_t arg)
 
 while (strcmp(msg,"exit") != 0)
     {
      printf("%s:",nickname);
      gets(msg);
      write(connmtt, &msg, sizeof(msg));
     }
     pthread_exit( (pthread_addr_t) 1);
     return 0;
    }
 
void * pread_tc(pthread_addr_t arg)
    {
     while (strcmp(rmsg,"exit") != 0)
     {
      write(connmtt, &rmsg, sizeof(rmsg),);
      printf("Server:%s",rmsg);
     }
     pthread_exit( (pthread_addr_t) 1);
     return 0;
    }
 
 
main()
 
  if ( (inadr = inet_addr(ipaddr)) != -1)
    host = gethostbyaddr((char *) &inadr, sizeof(inadr), AF_INET);
  else
    host = gethostbyname(ipaddr);
 if (host == 0)    perror("host");
 
 addr.sin_family = AF_INET;
 addr.sin_port	 = htons(port);
 memcpy(&addr.sin_addr, host->h_addr_list[0],sizeof(addr.sin_addr));
 
 if ( (connmtt = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
     perror("socket");
     exit(0);
    }
 if ( connect(connmtt, (struct sockaddr *) &addr, sizeof(addr)) == 0)
    {
      printf("LOGIN:");
      gets(nickname);
      pthread_create( &pread, pthread_attr_default, pread_tc,
(pthread_addr_t)nickname);
      pthread_create( &psend, pthread_attr_default, psend_tc,
(pthread_addr_t)nickname);
    }
    else
    {
     perror("connect");
     exit(0);
    }
 
  pthread_join(psend,&status);
  pthread_join(pread,&status);
 
 
 
Server:
 
/* Monitor Server */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <socket.h>
#include <in.h>
#include <inet.h>
#include <netdb.h>
#include <unixio.h>
#include <types.h>
#include <time.h>
#include <pthread.h>
 
#define port		2233
#define max_conn	10
 
int			sock_tcpip,
			conn_tcpip[max_conn],
                 	preads[max_conn],
			psends[max_conn],
                 	sopt = 1,
			conn_num;
 
char			recvv[BUFSIZ],
			sendv[BUFSIZ];
 
struct sockaddr_in	addr;
 
unsigned int		addr_len = sizeof(struct sockaddr_in);
 
pthread_t		pread[max_conn];
pthread_t		psend[max_conn];
 
pthread_addr_t		*status;
 
void * ts_read(pthread_addr_t arg)
   {
    int			conn_num;
    conn_num = (int)arg;
    while (strcmp(recvv,"exit") != 0)
       {
        read(conn_tcpip[conn_num], &recvv, sizeof(recvv));
printf("\nClient:%s",recvv);
       }
    preads[conn_num]= 0;
    pthread_exit( (pthread_addr_t) 1);
 
    return 0;
   }
 
void * ts_send(pthread_addr_t arg)
   {
    int			conn_num;
    conn_num = (int)arg;
    while (strcmp(sendv,"exit") != 0)
       {
        write(conn_tcpip[conn_num], &sendv, sizeof(sendv));
       }
    psends[conn_num]= 0;
    pthread_exit( (pthread_addr_t) 1);
    return 0;
   }
 
main()
   {
    printf("INITIALIZE SOCKET ...");
    if ( (sock_tcpip = socket(AF_INET, SOCK_STREAM, 0) ) == -1)
       {
        printf("                       [FAIL]\n");
       }
    else
       {
        printf("                       [PASS]\n");
       }
    printf("SETTING SOCKETOPTIONS...");
    if ( setsockopt(sock_tcpip, SOL_SOCKET, SO_REUSEADDR, &sopt,
sizeof(sopt)) == -1)
       {
        printf("                    [FAIL]\n");
       }
    else
       {
        printf("                    [PASS]\n");
       }
    addr.sin_family = AF_INET;
    addr.sin_port   = htons(port);
    memset(&addr.sin_addr, 0, sizeof(addr.sin_addr));
    printf("BINDING SOCKET...");
    if ( bind(sock_tcpip, (struct sockaddr *) &addr, sizeof(addr)) == -1)
       {
        printf("                           [FAIL]\n");
       }
    else
       {
        printf("                           [PASS]\n");
       }
        for (conn_num = 0; conn_num < max_conn; conn_num ++)
         {	printf("LISTENIG FOR CONNECTIONS...");
          if ( listen(sock_tcpip, max_conn) == -1)
          {
           printf("                 [FAIL]\n");
          }
        else
          {
           printf("                 [PASS]\n");
          }
          printf("ACCEPT CONNECTION (%d)...",conn_num);
        if ( (conn_tcpip[conn_num] = accept(sock_tcpip, (struct sockaddr *)
&addr, &addr_len)) == -1)
           {
            printf("                    [FAIL]\n");
           }
        else
           {
            printf("                    [PASS]\n");
            preads[conn_num]=1;
            pthread_create(&pread[conn_num], pthread_attr_default,
            ts_read, (pthread_addr_t) conn_num);
            psends[conn_num]=1;
            pthread_create(&psend[conn_num], pthread_attr_default,
            ts_send, (pthread_addr_t) conn_num);
           }
       }
    for (conn_num = 0; conn_num < max_conn; conn_num ++)
       {
        if (psends[conn_num] != 0)
          pthread_join(psend[conn_num], *status);
        if (preads[conn_num] != 0)
          pthread_join(pread[conn_num], *status);
       }
   }
 
 
Thank you very much for help !
 
 


The Answer is :

 
  OpenVMS Alpha V7.x releases provide full support for multi-threading.
  Though the DECthreads RTL is available and is cross-platform compatible,
  OpenVMS VAX and earlier OpenVMS Alpha releases do not and will not provide
  the kernel support necessary for true parallel multi-threaded operations.
 
  That said, the OpenVMS Wizard strongly recommends the use of the sys$qio
  interface for this purpose.  Potentially using threads, or using ASTs...
  Examples of the sys$qio calls are available in UCX$EXAMPLES: in TCP/IP
  Services releases prior to V5.0, and in TCPIP$EXAMPLES: in V5.0 and later.
 
  Information on application synchronization is included in topic 1661.*,
  and can be of central interest with multi-threaded applications.
 
 

answer written or last revised on ( 17-NOV-1999 )

» close window