HP OpenVMS Systemsask the wizard |
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.
|