![]() |
![]() 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.
|