LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Client/Server chat program (https://www.linuxquestions.org/questions/programming-9/client-server-chat-program-4175415420/)

joyce092130 07-07-2012 10:54 AM

Client/Server chat program
 
How can i make my codes in hello world program into a single chat program where the client can send messages to the server and the server can send replies to the client?
here are my codes:

Code:

server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>

int _GetHostName(char *buffer, int length);

const char MESSAGE[]="Hello, World!\n";
const int BACK_LOG=5;

int main(int argc, char *argv[]){
  int serverSocket=0,on=0,port=0,status=0,childPid=0;
  struct hostent *hostPtr=NULL;
  char hostname[80]="";
  struct sockaddr_in serverName={0};

  if(2!=argc){
    fprintf(stderr,"Usage: %s <port>\n",argv[0]);
    exit(1);
  }
  port=atoi(argv[1]);
  serverSocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
  if(-1==serverSocket){
    perror("socket()");
    exit(1);
  }

  on=1;
  status=setsockopt(serverSocket,SOL_SOCKET,SO_REUSEADDR,
                    (const char*)&on,sizeof(on));
  if(-1==status){
    perror("setsockopt(...,SO_REUSEADDR,...)");
  }
{
  struct linger linger={0};
  linger.l_onoff=1;
  linger.l_linger=30;
  status=setsockopt(serverSocket,SOL_SOCKET,SO_LINGER,
                    (const char*)&linger,sizeof(linger));
  if(-1==status){
    perror("setsockopt(...,SO_LINGER,...)");
  }
 }

  status=_GetHostName(hostname,sizeof(hostname));
  if(-1==status){
    perror("_GetHostName()");
    exit(1);
  }

  hostPtr=gethostbyname(hostname);
  if(NULL==hostPtr){
    perror("gethostbyname()");
    exit(1);
  }
 
  (void)memset(&serverName,0,sizeof(serverName));
  (void)memcpy(&serverName.sin_addr,hostPtr->h_addr,hostPtr->h_length);

  serverName.sin_family=AF_INET;
  serverName.sin_port=htons(port);

  status=bind(serverSocket,(struct sockaddr*)&serverName,sizeof(serverName));
  if(-1==status){
  perror("bind()");
  exit(1);
  }

  status=listen(serverSocket,BACK_LOG);
  if(-1==status){
    perror("listen()");
    exit(1);
  }

  for(;;){
    struct sockaddr_in clientName={0};
    int slaveSocket, clientLength=sizeof(clientName);

    (void)memset(&clientName,0,sizeof(clientName));

    slaveSocket=accept(serverSocket,
                (struct sockaddr*)&clientName,&clientLength);
    if(-1==slaveSocket){
      perror("accept()");
      exit(1);
    }

  childPid=fork();

  switch(childPid){

  case -1:/*ERROR */
          perror("fork()");
          exit(1);
  case 0 :/*child process */
          close(serverSocket);
          if(-1==getpeername(slaveSocket,
                  (struct sockaddr*)&clientName,&clientLength)){
            perror("getpeername()");
          }else{
              printf("Connection request from %s\n",
                      inet_ntoa(clientName.sin_addr));
            } 
           
          write(slaveSocket,MESSAGE,strlen(MESSAGE));
          close(slaveSocket);
          exit(0);
    default:/*parent process */
          close(slaveSocket);
    }
    }
    return 0;
  }

  int _GetHostName(char *buffer,int length){
    struct utsname sysname={0};
    int status=0;

    status=uname(&sysname);
    if(-1!=status){
      strncpy(buffer,sysname.nodename,length);
    }
    return(status);
  }


Code:

client.c


#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

int main(int argc,char *argv[]){
  int clientSocket,remotePort,status=0;
  struct hostent *hostPtr=NULL;
  struct sockaddr_in serverName={0};
  char buffer[256]="";
  char *remoteHost=NULL;

  if(3!=argc){
    fprintf(stderr,"Usage: %s <serverHost> <serverPort>\n",argv[0]);
    exit(1);
  }
  remoteHost=argv[1];
  remotePort=atoi(argv[2]);
  clientSocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
  if(-1==clientSocket){
    perror("socket()");
    exit(1);
  }

  hostPtr=gethostbyname(remoteHost);
  if(NULL==hostPtr){
    hostPtr=gethostbyaddr(remoteHost,strlen(remoteHost),AF_INET);
    if(NULL==hostPtr){
      perror("Error resolving server address ");
      exit(1);
    }
  }
  serverName.sin_family=AF_INET;
  serverName.sin_port=htons(remotePort);
  (void)memcpy(&serverName.sin_addr,hostPtr->h_addr,hostPtr->h_length);
  status=connect(clientSocket,(struct sockaddr*)&serverName,
                sizeof(serverName));
  if(-1==status){
    perror("connect()");
    exit(1);
  }

  while(0<(status=read(clientSocket,buffer,sizeof(buffer)-1)))
  printf("%d: %s",status,buffer);
  if(-1==status)perror("read()");
  close(clientSocket);
  return 0;
  }

thank u!

VisionIncision 07-09-2012 08:46 AM

Could you possibly repost the source, but in code tags, so that it is correctly indented, etc.

joyce092130 07-09-2012 09:03 AM

sorry but idk how to do that, can u teach me how please. thanks.

amboxer21 07-11-2012 08:52 PM

That is a huge mess! You are casting things that do not need casting. Your using functions wrong. Your code is sloppy, and in random order. I am not even going to attempt to do anything with this but I will provide you with a synchronous chat I wrote.

CLIENT:
Code:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>

int main(int argc, char *argv[]) {
int sockfd, portno, connector, yes = 1;
ssize_t bytes_read, bytes_written; 
struct hostent *server;
struct sockaddr_in serv_addr, cli_addr;
char buffer[4096];

        if(argc < 3)
        {
        fprintf(stderr, "Ussage: %s + IP Address + port No.\n", argv[0]);
        exit(0);
        }

sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if(sockfd < 0) {
        printf("SOCKET(-1) error ---> %s.\n", strerror(errno));
        exit(EXIT_FAILURE);
        }

        if(sockfd == 0) {
        printf("SOCKET(0) error ---> %s.\n", strerror(errno));
        exit(EXIT_FAILURE);
        }


setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

bzero(&serv_addr, sizeof(serv_addr));
server = gethostbyname(argv[1]);
        if(server == NULL) {
        fprintf(stderr, "No such host.\n");
        printf("%s\n", strerror(errno));
        exit(EXIT_FAILURE);
        }

portno = atoi(argv[2]);
serv_addr.sin_family = AF_INET;
memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
serv_addr.sin_port = htons(portno);

        connector = connect(sockfd, (const struct sockaddr *) &serv_addr, sizeof(serv_addr));
        if(connector < 0) {
        fprintf(stderr, "%s. CONNECT()\n", strerror(errno));
        exit(EXIT_FAILURE);
        }
                else {
                printf("Made a connection to %s\n", inet_ntoa(serv_addr.sin_addr));
                }

for( ; ; )
{
       
printf("Message: ");
fgets(buffer, sizeof(buffer), stdin);
bytes_written = write(sockfd, buffer, sizeof(buffer));
        if(bytes_written == 0) {
        printf("WRITE(0) error ---> %s.\n", strerror(errno));
        printf("Nothing was written.\n");
        break;
        }

memset(buffer, 0, sizeof(buffer));
bytes_read = read(sockfd, buffer, sizeof(buffer));
        if(bytes_read < 0) {
        //fprintf(stderr, "Error reading message from %s\n", inet_ntoa(cli_addr.sin_addr));
        printf("READ(c) error ---> %s.\n", strerror(errno));
        exit(EXIT_FAILURE);
        }

        //Test to see if the buffer is blank.
        if(bytes_read == 0) {
        printf("READ(0) error ---> %s.\n", strerror(errno));
        exit(EXIT_SUCCESS);
        }

        fprintf(stdout, "server: %s", buffer);

}

close(sockfd);

return 0;
}

SERVER:
Code:

#include <stdio.h>
#include <netdb.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(int argc, char *argv[]) {
int sockfd, newsockfd, portno, binder, listener;
ssize_t bytes_read, bytes_written;
struct sockaddr_in serv_addr, cli_addr;
struct hostent *server;
int yes = 1;
socklen_t clilen;
char data[4096];

        if(argc < 3) {
        printf("Usage: %s ip address - port number\n", argv[0]);
        exit(EXIT_FAILURE);
        }

sockfd = socket(AF_INET, SOCK_STREAM, 0);

        if(sockfd == 0) {
        printf("SOCKET(0) error ---> %s.\n", strerror(errno));
        exit(EXIT_FAILURE);
        }

        if(sockfd < 0) {
        printf("SOCKET(-1) error ---> %s.\n", strerror(errno));
        exit(EXIT_FAILURE);
        }

                else if(sockfd) {

                  do {
                    {
                    printf("waiting for a connection.\n");
                    }
                  } while(!accept);
                }

setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

bzero(&serv_addr, sizeof(serv_addr));
server = gethostbyname(argv[1]);

        if(server == NULL) {
        fprintf(stderr, "No such host.\n");
        printf("%s\n", strerror(errno));
        exit(EXIT_FAILURE);
        }

portno = atoi(argv[2]);
serv_addr.sin_family = AF_INET;
memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
serv_addr.sin_port = htons(portno);

binder = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));

        if(binder < 0) {
        printf("BIND(-1) error ---> %s.\n", strerror(errno));
        exit(EXIT_FAILURE);
        }

listener = listen(sockfd, 20);

        if(listener < 0) {
        printf("LISTEN(-1) error ---> %s.\n", strerror(errno));
        exit(EXIT_FAILURE);
        }

clilen = sizeof(cli_addr);

newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);

        if(newsockfd == 0) {
        printf("ACCEPT(0) error ---> %s.\n", strerror(errno));
        exit(EXIT_FAILURE);
        }

        if(newsockfd < 0) {
        printf("ACCEPT(-1) error ---> %s.\n", strerror(errno));
        exit(EXIT_FAILURE);
        }

        if(accept) {
          {
          printf("Received connection from %s.\n", inet_ntoa(cli_addr.sin_addr));
          }       
        }

for( ; ; ) {
bytes_read = read(newsockfd, data, sizeof(data));

        if(bytes_read < 0) {
        printf("READ(-1) error ---> %s.\n", strerror(errno));
        exit(EXIT_FAILURE);
        }

        if(bytes_read == 0) {
        printf("READ(0) error ---> %s.\n", strerror(errno));
        exit(EXIT_SUCCESS);
        }

        fprintf(stdout, "Client: %s", data);

printf("message: ");
fgets(data, sizeof(data), stdin);
bytes_written = write(newsockfd, data, strlen(data));

        if(bytes_written < 0) {
        printf("WRITE(-1) error ---> %s.\n", strerror(errno));
        exit(EXIT_FAILURE);
        }
}

close(newsockfd);
close(sockfd);

return 0;
}

Please do not just copy and paste my code. You won't learn that way! Check it out and pick it apart. If you have any questions, I'll do my best to answer.

joyce092130 07-11-2012 09:20 PM

thank you. i will try ur codes then.

joyce092130 07-11-2012 09:41 PM

hi amboxer21!

after trying ur codes, here is the result of my compilation:
Code:

Joyce@UWTG-MJ ~
$ gcc -Wall -o server serverchat.c
serverchat.c: In function ‘main’:
serverchat.c:38:13: warning: the address of ‘accept’ will always evaluate as ‘true’
serverchat.c:84:4: warning: the address of ‘accept’ will always evaluate as ‘true’

Joyce@UWTG-MJ ~
$ ./serverchat 350
Usage: ./serverchat ip address - port number

Joyce@UWTG-MJ ~
$ ./serverchat 50
Usage: ./serverchat ip address - port number

Joyce@UWTG-MJ ~
$ ./serverchat 50
Usage: ./serverchat ip address - port number

Code:

Joyce@UWTG-MJ ~
$ gcc -Wall -o client clientchat.c
clientchat.c: In function ‘main’:
clientchat.c:16:31: warning: unused variable ‘cli_addr’

Joyce@UWTG-MJ ~
$ ./clientchat UWTG-MJ 50
Connection refused. CONNECT()

Joyce@UWTG-MJ ~
$ gcc -Wall -o client clientchat.c
clientchat.c: In function ‘main’:
clientchat.c:16:31: warning: unused variable ‘clie_addr’

Joyce@UWTG-MJ ~
$ ./clientchat UWTG-MJ 50
Connection refused. CONNECT()

what shall i do with this?
thank u.

amboxer21 07-11-2012 09:56 PM

Quote:

Originally Posted by joyce092130 (Post 4725623)
hi amboxer21!

after trying ur codes, here is the result of my compilation:
Code:

Joyce@UWTG-MJ ~
$ gcc -Wall -o server serverchat.c
serverchat.c: In function ‘main’:
serverchat.c:38:13: warning: the address of ‘accept’ will always evaluate as ‘true’
serverchat.c:84:4: warning: the address of ‘accept’ will always evaluate as ‘true’

Joyce@UWTG-MJ ~
$ ./serverchat 350
Usage: ./serverchat ip address - port number

Joyce@UWTG-MJ ~
$ ./serverchat 50
Usage: ./serverchat ip address - port number

Joyce@UWTG-MJ ~
$ ./serverchat 50
Usage: ./serverchat ip address - port number

Code:

Joyce@UWTG-MJ ~
$ gcc -Wall -o client clientchat.c
clientchat.c: In function ‘main’:
clientchat.c:16:31: warning: unused variable ‘cli_addr’

Joyce@UWTG-MJ ~
$ ./clientchat UWTG-MJ 50
Connection refused. CONNECT()

Joyce@UWTG-MJ ~
$ gcc -Wall -o client clientchat.c
clientchat.c: In function ‘main’:
clientchat.c:16:31: warning: unused variable ‘clie_addr’

Joyce@UWTG-MJ ~
$ ./clientchat UWTG-MJ 50
Connection refused. CONNECT()

what shall i do with this?
thank u.

When you ran my program it should have gave you directions if you didn't run it right. Anyhow, ignore the warnings.

ASSUMING YOU ARE RUNNING BOTH ON THE SAME MACHINE.

run the server first and run it with
Code:

./serverchat 127.0.0.1 12345
then run the client with
Code:

./clientchat 127.0.0.1 12345
You could use any ip address's or any ports higher than 1024.

On a side note; It's not cool to copy and paste peoples hard work! I hope you are using this to learn!

joyce092130 07-11-2012 10:08 PM

thank u. i will use your work as a reference to improve my codes.
great help! :D

hanspeare 07-15-2012 07:14 AM

hello amboxer 21, i am very much interested in the codes you have given. can you suggest me any compiler for C codes that could simply make it RUN right? please..

hanspeare 07-15-2012 07:41 AM

shall we need two computers (one for client and another one for the server )in these codes?

joyce092130 07-15-2012 08:02 AM

hanspeare, u dont need 2 computers, just one will do.
i used codeblocks to write my codes and cygwin compiler and it worked.

hanspeare 07-15-2012 08:09 AM

cgwyn is a huge program and take time to install,,have you tried it to another C compiler that it also works?

joyce092130 07-15-2012 08:13 AM

nah, haven't tried other compilers.

hanspeare 07-15-2012 09:00 AM

how to make a chat if we will be using only one computer? does it mean we have to use two cygwin terminals at one time?

joyce092130 07-15-2012 09:11 AM

thats right, one for the server and one for the client.


All times are GMT -5. The time now is 08:54 AM.