c - full duplex communication between server & client -
i want make code full duplex communication between server & client using code.
got error in receive-message thread server side & in send-message thread client side.
please me solve errors & suggest me if other changes required. :)
server.cpp
int newsockfd, n; void error(const char *msg) { perror(msg); exit(1); } void* recvfn( void* data ) { char buffer[256]; while(n==0){ memset( buffer, sizeof(buffer), 0); n = recv(newsockfd,buffer,255,msg_peek); if(n>0){ printf("cliet: "); printf("%s",buffer); } } return null; } void* sendfn( void* data ) { char temp[255], buffer[255]; while(n==0){ memset( buffer, sizeof(buffer), 0); fgets(temp,255,stdin); sprintf(buffer,"clent: %s",temp); n = send(newsockfd,buffer,strlen(buffer),msg_eor); } return null; } int main(int argc, char *argv[]) { int sockfd, portno; socklen_t clilen; struct sockaddr_in serv_addr, cli_addr; if (argc < 2) { fprintf(stderr,"error, no port provided\n"); exit(1); } pthread_t recvthread, sendthread; sockfd = socket(af_inet, sock_stream, 0); if (sockfd < 0) error("error opening socket"); memset( &serv_addr, sizeof(serv_addr), 0); portno = atoi(argv[1]); serv_addr.sin_family = af_inet; serv_addr.sin_addr.s_addr = inaddr_any; serv_addr.sin_port = htons(portno); int on = 1; if ( setsockopt( sockfd, sol_socket, so_reuseaddr, &on, sizeof( on ) ) != 0 ) { close( sockfd ); return -1; } if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("error on binding"); listen(sockfd,5); clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) error("error on accept"); n = 0; int rc; rc = pthread_create( &recvthread, null, recvfn, null); if(rc){ printf("error in receive-message thread\n"); return -1; } rc = pthread_create( &sendthread, null, sendfn, null); if(rc){ printf("error in send-message thread\n"); return -1; } close(newsockfd); close(sockfd); pthread_cancel(recvthread); pthread_cancel(sendthread); return 0; }
client.cpp
int sockfd, n; void* recvfn( void* data ) { char buffer[255]; while( n==0 ){ memset( buffer, sizeof(buffer), 0); n = recv(sockfd,buffer,255,msg_peek); if(n>0){ printf("server: "); printf("%s",buffer); } } return null; } void* sendfn( void* data ) { char temp[255], buffer[255]; while( n==0 ){ memset( buffer, sizeof(buffer), 0); fgets(temp,255,stdin); sprintf(buffer,"clent: %s",temp); n = send(sockfd,buffer,strlen(buffer),msg_eor); } return null; } void error(const char *msg) { perror(msg); exit(0); } int main(int argc, char *argv[]) { int portno; struct sockaddr_in serv_addr; struct hostent *server; char buffer[256]; if (argc < 3) { fprintf(stderr,"usage %s hostname port\n", argv[0]); exit(0); } pthread_t recvthread, sendthread; sockfd = socket(af_inet, sock_stream, 0); if (sockfd < 0) error("error opening socket"); portno = atoi(argv[2]); server = gethostbyname(argv[1]); if (server == null) { fprintf(stderr,"error, no such host\n"); exit(0); } memset( &serv_addr, sizeof(serv_addr), 0); serv_addr.sin_family = af_inet; memcpy((char *)server->h_addr,(char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("error on connecting"); n = 0; int rc; rc = pthread_create( &sendthread, null, sendfn, null); if(rc){ printf("error in send-message thread\n"); return -1; } rc = pthread_create( &recvthread, null, recvfn, null); if(rc){ printf("error in receive-message thread\n"); return -1; } close(sockfd); pthread_cancel(recvthread); pthread_cancel(sendthread); return 0; }
your pthread_mutex
operations pointless. you're referring local variables inside mutex lock other n
, should local in each thread , newsockfd
should not global, see below. (don't think function calls recv
should have local variable capture number of bytes read, , not share silly little temporary variable globally other threads?)
your main thread in while loop, creating threads crazy. also, inside loop has closed 1 , accepted socket, right after creating threads.
you forgot put accept
inside loop, evidently.
also seem think main loop somehow wait pair of threads terminate before launching new ones. missing pthread_join
calls wait threads finish communicating. if want thread keep going while main loop accepts new connections using new threads, should make threads detached pthread_detached
or using thread-creation attribute makes them detached. non-detached threads not pthread_join
-ed continue occupy resources.
speaking of shutdown, correct condition threads keep looping while n == 0
? n
set nonzero 1 of threads, shutdown condition met. nonzero value normal: bytes written or read. reader should terminate loop when there fatal receive error on socket, or read returns zero.
also, evaluating n == 0
outside of mutex!
if want accept multiple concurrent connections, each pair of threads, cannot use single global socket. have give each pair of threads own socket. 2 threads within each pair not have use mutex share socket. socket calls thread-safe in kernel , threads not both doing reads or writes; 1 reading , 1 writing.
other problems
your sender keeps sending uninitialized garbage: buffer never set contain data.
you have bzero
of 256 bytes on array of 255 bytes.
also
don't use bzero
(or bcopy
, etc). it's bsd-ism 1980's. c language standardized in 1989 ansi , after in 1990 iso. @ time, had library functions memset
, memcpy
, memmove
.
i think 22 years later, safe retire bcopy
, dontcha think?
Comments
Post a Comment