Solved

About socket programming.......

Posted on 2004-07-30
3
909 Views
Last Modified: 2010-04-15
Hi guys,

  I have a small problem with my program. the program looks big, but it is very simple..

 I have a client and server program.. The output is to echo whatever i type at client back to itself..

 am using threads...

 everything works fine, means like it compiled without any errors, but while executing, means while i type something like Hi, its not echoing it back.. it just gets stuck there ...

wat might b the problem... with the code..

here r my files...

1. header.h
2. thrdsdcli.c
3.thrdsdser.c

code of header.h

#include<stdio.h>
#include<sys/socket.h>
#include<errno.h>
#include<sys/types.h>
#include<signal.h>
#include<time.h>
#include<string.h>
#include<sys/types.h>
#include<stdlib.h>
#include<pthread.h>



static pthread_key_t rl_key;
static pthread_once_t rl_once=PTHREAD_ONCE_INIT;

static void readline_destructor(void *ptr)
{
  free(ptr);
}

static void readline_once(void)
{
  pthread_key_create(&rl_key,readline_destructor);
}

typedef struct
{
  int rl_cnt;
  char rl_buf[256];
  char *rl_bufptr;

}rline;



static ssize_t my_read(rline *tsd,int fd,char *ptr)
{
  if(tsd->rl_cnt<=0)
    {
      if((tsd->rl_cnt=read(fd,tsd->rl_buf,256))<0)
        {
          //      if(errno==EINTR)
          //goto again;
          return(-1);
        }
      else if(tsd->rl_cnt==0)
        return(0);
      tsd->rl_bufptr=tsd->rl_buf;
    }
  tsd->rl_cnt--;
  *ptr=*tsd->rl_bufptr++;
  return(1);
}
ssize_t readline(int fd,void *vptr,size_t maxlen)
{
  int n,rc;
    char c,*ptr;
  rline *rld;

  pthread_once(&rl_once,readline_once);

  if((rld=pthread_getspecific(rl_key))==NULL)
    {
      rld=calloc(1,sizeof(rline));
      pthread_setspecific(rl_key,rld);
    }
  ptr=vptr;

  for(n=1;n<maxlen;n++)
    {
      if((rc=my_read(rld,fd,&c))==1)
        {
          *ptr++=c;
          if(c=='\n')
            break;
        }
      else if(rc==0)
        {
          if(n==1)
            return(0);
          else
            break;
        }
      else
        return(-1);
    }
  *ptr=0;
  return(0);
}

code for thrdsdcli.c
===============

#include "header.h"

static int sockfd;
static FILE *fp;

void *copyto(void *arg)
{
  char sendline[256];
  while(fgets(sendline,256,fp)!=NULL)
    write(sockfd,sendline,strlen(sendline));

  shutdown(sockfd,SHUT_WR);
  return(NULL);
}

void str_cli(FILE *fp_arg,int sockfd_arg)
{
  char recvline[256];
  pthread_t tid;

  sockfd=sockfd_arg;
  fp=fp_arg;

  pthread_create(&tid,NULL,copyto,NULL);

  while(readline(sockfd,recvline,256)>0)
    fputs(recvline,stdout);
}

int main(int argc,char **argv)
{
  struct sockaddr_in servaddr;

  if(argc!=2)
    perror("No IP Address");

  sockfd=socket(AF_INET,SOCK_STREAM,0);

  bzero(&servaddr,sizeof(servaddr));

  servaddr.sin_family=AF_INET;
  servaddr.sin_port=htons(9786);
  servaddr.sin_addr.s_addr=inet_addr(argv[1]);

  if((connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)))<0)
    perror("Connection Failed");

  str_cli(stdin,sockfd);

  exit(0);
}


code for thrdsser.c
================

#include "header.h"

void str_echo(int sockfd)
{
  ssize_t n;
  char line[256];

  for(;;)
    {
      if((n=readline(sockfd,line,256))==0)
        return;

      write(sockfd,line,n);
    }
}


static void *doit(void *arg)
{
  pthread_detach(pthread_self());

  str_echo((int)arg);
  close((int)arg);

  return(NULL);
}


int main()
{
  int listenfd,connfd;
  pthread_t tid;
  socklen_t addrlen,len;
  struct sockaddr_in cliaddr;
  struct sockaddr_in servaddr;

  listenfd=socket(AF_INET,SOCK_STREAM,0);

  bzero(&servaddr,sizeof(servaddr));

  servaddr.sin_family=AF_INET;
  servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
  servaddr.sin_port=htons(9786);

  bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

  listen(listenfd,5);

  for( ; ; )
    {
      len=sizeof(cliaddr);
      connfd=accept(listenfd,(struct sockaddr *)&cliaddr,&len);
      pthread_create(&tid,NULL,&doit,(void *)connfd);
  }

}

to compile
=======

gcc -o thrdsdser thrdsdser.c -lsocket -lpthread -lnsl -lrt
gcc -o thrdsdcli thrdscli.c -lsocket -lpthread -lnsl -lrt

to run
======
./thrdsdser   [at server]

./thrdscli 147.26.102.131 [its my machines ip address to which am connected]



i need help for this.

bye
aman



0
Comment
Question by:amankhan
3 Comments
 
LVL 22

Expert Comment

by:grg99
ID: 11682373
First I'd add a lot of debug lines to check the error returns from all the socket functions.  

Then I'd test each half separately, using telnet or some other already existing client and server to test out each half.   It's mighty frustrating to debug a buggy client and a buggy server at the same time.



0
 
LVL 45

Accepted Solution

by:
sunnycoder earned 500 total points
ID: 11682833

static void *doit(void *arg)
{
  pthread_detach(pthread_self());

  str_echo((int)arg);    >>>>> server calls str_echo to do socket operations
  close((int)arg);

  return(NULL);
}


void str_echo(int sockfd)
{
  ssize_t n;
  char line[256];

  for(;;)
    {
      if((n=readline(sockfd,line,256))==0)   >>>> server expects to read a line from the socket on the other hand, client is also expecting to read something from the socket .... read is a blocking call and both server and client are blocked on it hoping to receive something ... since no one is sending, both of them wait forever .... change this loop to read from stdin and write to socket and everything should work fine .... However, like grg99, I too would recommend that you add checks for return values of socket calls
        return;

      write(sockfd,line,n);
    }
}

0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 11700613
Hi amankhan,

    Are you clear with what you intend to do?
    When you are typing something at the clients end and what client to echo it back to terminal, what is the necesity of server there?
    Do you want the message to go from client to server and then back from server to client and then displayed!?

    So, if you could make the intention clear, then we can try to give more valuable suggestions.

-ssnkumar
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now