Solved

c/tcp socket programming how to send recv

Posted on 2008-10-19
5
7,617 Views
Last Modified: 2012-05-05
I have two files - client and server. I can get them to connect using tcp sockets but need to know once a connection is established how can i then have the client send a message to the server and the server send a message back? two files are below
/*

** server.c -- a stream socket server demo

*/
 

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

#include <arpa/inet.h>

#include <sys/wait.h>

#include <signal.h>
 

#define PORT "3492"  // the port users will be connecting to

#define MAXDATASIZE 100 // max number of bytes we can get at once 

#define BACKLOG 10     // how many pending connections queue will hold
 

void sigchld_handler(int s)

{

    while(waitpid(-1, NULL, WNOHANG) > 0);

}
 

// get sockaddr, IPv4 or IPv6:

void *get_in_addr(struct sockaddr *sa)

{

    if (sa->sa_family == AF_INET) {

        return &(((struct sockaddr_in*)sa)->sin_addr);

    }
 

    return &(((struct sockaddr_in6*)sa)->sin6_addr);

}
 

int main(void)

{

    int sockfd, new_fd;  // listen on sock_fd, new connection on new_fd

    struct addrinfo hints, *servinfo, *p;

    struct sockaddr_storage their_addr; // connector's address information

    socklen_t sin_size;

    struct sigaction sa;

    int yes=1;

    char s[INET6_ADDRSTRLEN];

    int rv;
 

    memset(&hints, 0, sizeof hints);

    hints.ai_family = AF_UNSPEC;

    hints.ai_socktype = SOCK_STREAM;

    hints.ai_flags = AI_PASSIVE; // use my IP
 

    if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) == -1) {

        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));

        return 1;

    }
 

    // loop through all the results and bind to the first we can

    for(p = servinfo; p != NULL; p = p->ai_next) {

        if ((sockfd = socket(p->ai_family, p->ai_socktype,

                p->ai_protocol)) == -1) {

            perror("server: socket");

            continue;

        }
 

        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,

                sizeof(int)) == -1) {

            perror("setsockopt");

            exit(1);

        }
 

        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {

            close(sockfd);

            perror("server: bind");

            continue;

        }
 

        break;

    }
 

    if (p == NULL)  {

        fprintf(stderr, "server: failed to bind\n");

        return 2;

    }
 

    freeaddrinfo(servinfo); // all done with this structure
 

    if (listen(sockfd, BACKLOG) == -1) {

        perror("listen");

        exit(1);

    }
 

    sa.sa_handler = sigchld_handler; // reap all dead processes

    sigemptyset(&sa.sa_mask);

    sa.sa_flags = SA_RESTART;

    if (sigaction(SIGCHLD, &sa, NULL) == -1) {

        perror("sigaction");

        exit(1);

    }
 

    printf("server: waiting for connections...\n");
 

    while(1) {  // main accept() loop

        sin_size = sizeof their_addr;

        new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);

        if (new_fd == -1) {

            perror("accept");

            continue;

        }
 

        inet_ntop(their_addr.ss_family,

            get_in_addr((struct sockaddr *)&their_addr),

            s, sizeof s);

        printf("server: got connection from %s\n", s);
 

        if (!fork()) { // this is the child process

            close(sockfd); // child doesn't need the listener

            if (send(new_fd, "Hello, world!", 13, 0) == -1)

                perror("send");

            close(new_fd);

            exit(0);

        }
 

        close(new_fd);  // parent doesn't need this

       	

        

    }
 

    return 0;

}
 
 
 
 
 

-------------------------------------------------------------------------
 
 
 
 
 
 
 

/*

** client.c -- a stream socket client demo

*/
 

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <errno.h>

#include <string.h>

#include <netdb.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>
 

#include <arpa/inet.h>
 

#define PORT "3492" // the port client will be connecting to 
 

#define MAXDATASIZE 100 // max number of bytes we can get at once 
 

// get sockaddr, IPv4 or IPv6:

void *get_in_addr(struct sockaddr *sa)

{

    if (sa->sa_family == AF_INET) {

        return &(((struct sockaddr_in*)sa)->sin_addr);

    }
 

    return &(((struct sockaddr_in6*)sa)->sin6_addr);

}
 

int queryServer(char* hostname, char *searchterm) {

    int sockfd, numbytes;  

    char buf[MAXDATASIZE];

    struct addrinfo hints, *servinfo, *p;

    int rv;

    char s[INET6_ADDRSTRLEN];
 

/*

    if (argc != 2) {

        fprintf(stderr,"usage: client hostname\n");

        exit(1);

    }

*/
 

    memset(&hints, 0, sizeof hints);

    hints.ai_family = AF_UNSPEC;

    hints.ai_socktype = SOCK_STREAM;
 

    if ((rv = getaddrinfo(hostname, PORT, &hints, &servinfo)) != 0) {

        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));

        return 1;

    }
 

    // loop through all the results and bind to the first we can

    for(p = servinfo; p != NULL; p = p->ai_next) {

        if ((sockfd = socket(p->ai_family, p->ai_socktype,

                p->ai_protocol)) == -1) {

            perror("client: socket");

            continue;

        }
 

        if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {

            close(sockfd);

            perror("client: connect");

            continue;

        }
 

        break;

    }
 

    if (p == NULL) {

        fprintf(stderr, "client: failed to connect\n");

        return 2;

    }
 

    inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),

            s, sizeof s);

    printf("client: connecting to %s\n", s);
 

    freeaddrinfo(servinfo); // all done with this structure
 

    if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {

        perror("recv");

        exit(1);

    }
 

    buf[numbytes] = '\0';
 

    printf("client: received '%s'\n",buf);
 

    close(sockfd);    

  

  	return 0;

  

}
 

int main(int argc, char *argv[])

{

    if (argc != 3) {

        fprintf(stderr,"usage: client hostname searchterm\n");

        exit(1);

    }

	
 

	queryServer(argv[1], argv[2]);
 

    return 0;

}

Open in new window

0
Comment
Question by:mstrelan
5 Comments
 
LVL 45

Accepted Solution

by:
sunnycoder earned 500 total points
ID: 22751446
>the client send a message to the server and the server send a message back?
Right now your server is sending Hello World to the client. In same fashion, you can add a send in the client and a corresponding recv in the server followed by a send in the server and a recv in the client

client()
{
      connect
      send  -- send a message to server
      recv   -- recv the response
}

server()
{
       listen
       accept
       recv   -- recv client request
       send  -- send response
}

Also, you dont need a fork in the server
0
 
LVL 10

Author Comment

by:mstrelan
ID: 22751483
more details please? i need to know exactly where to add these send and receives, and also how does the client know the new socket number? do i need to rebind or anything?
0
 
LVL 10

Author Closing Comment

by:mstrelan
ID: 31507542
thanks i worked it out. i was trying to send back to the server after the socket was closed :P
0
 
LVL 17

Expert Comment

by:sweetfa2
ID: 22754042
You have two problems here.  Is it guaranteed that after a send you will always get a response.  If so you can just do a recv immediately after you do a send in your client.

Likewise, immediately after you receive a recv in the server you can do a send to forward it back again.

If however you cannot guarantee that a response will always be received then you need to set up separate threads to handle the recv and send parts of the code.
0
 

Expert Comment

by:Hemanth_hm
ID: 23062554

//CLIENT
 

#include<sys/socket.h>

#include<sys/types.h>

#include<netinet/in.h>

#include<unistd.h>

#include<stdlib.h>

#include<stdio.h>
 

int main(int argc,char *argv[])

{

  int create_socket,cont;

  int bufsize = 1024;

  char *buffer = malloc(bufsize);

  char fname[256];

  struct sockaddr_in address;
 

  if ((create_socket = socket(AF_INET,SOCK_STREAM,0)) > 0)

    printf("The Socket was created\n");

  address.sin_family = AF_INET;

  address.sin_port = htons(15000);

  inet_pton(AF_INET,argv[1],&address.sin_addr);
 

  if (connect(create_socket,(struct sockaddr *) &address,

              sizeof(address)) == 0)

    printf("The connection was accepted with the server %s...\n",

            argv[1]);

  printf("Enter The Filename to Request : "); scanf("%s",fname);

  send(create_socket, fname, sizeof(fname), 0);

  printf("Request Accepted... Receiving File...\n\n");

  printf("The contents of file are...\n\n");

  while((cont=recv(create_socket, buffer, bufsize, 0))>0) {

    write(1, buffer, cont);

  }

  printf("\nEOF\n");

  return close(create_socket);

}
 
 
 

//Server
 

/*Server*/
 

#include<sys/types.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include<sys/stat.h>

#include<unistd.h>

#include<stdlib.h>

#include<stdio.h>

#include<fcntl.h>
 

int main()

{

  int cont,create_socket,new_socket,addrlen,fd;

  int bufsize = 1024;

  char *buffer = malloc(bufsize);

  char fname[256];

  struct sockaddr_in address;
 

  if ((create_socket = socket(AF_INET,SOCK_STREAM,0)) > 0)

    printf("The socket was created\n");
 

  address.sin_family = AF_INET;

  address.sin_addr.s_addr = INADDR_ANY;

  address.sin_port = htons(15000);
 

  if (bind(create_socket,(struct sockaddr *)&address,sizeof(address)) == 0)

    printf("Binding Socket\n");

  listen(create_socket,3);

  addrlen = sizeof(struct sockaddr_in);

  new_socket = accept(create_socket,(struct sockaddr *)&address,&addrlen);
 

  if (new_socket > 0)

     printf("The Client %s is Connected...\n",

             inet_ntoa(address.sin_addr));

  recv(new_socket,fname, 255,0);

  printf("A request for filename %s Received..\n", fname);

  if ((fd=open(fname, O_RDONLY))<0)

    {perror("File Open Failed"); exit(0);}

  while((cont=read(fd, buffer, bufsize))>0) {

     send(new_socket,buffer,cont,0);

  }

  printf("Request Completed\n");

  close(new_socket);

  return close(create_socket);

}

Open in new window

0

Featured Post

ScreenConnect 6.0 Free Trial

Discover new time-saving features in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

932 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

11 Experts available now in Live!

Get 1:1 Help Now