Hey all!
So i've been working on a unix chat server and I think I've done a good job having no idea what I'm doing :-p. The only issue I'm running into is that I can't get it to go 1 to multiple. For instance, the idea is that any number of my friends can attach to the server and then the server will spit the message back to all of them. Can you help me with this?

My thoughts were to store the client's connections in a vector somehow and then that way it could always add new clients but I'm not sure how to do that.

Server Portion:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

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

#define BUF_SIZE 500
#define PORT 10122

int main(int argc,char * argv[]) {
  int s;
  int rtn;
  char buff[BUF_SIZE];
  struct sockaddr_in addr;
  int incoming_s;
  socklen_t incoming_len;

  s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  if (s == -1) {
    perror("Failed to get socket");
    exit(EXIT_FAILURE);
  }

  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = INADDR_ANY;
  addr.sin_port = htons(PORT);

  rtn = bind(s, (struct sockaddr*)&addr, sizeof(addr));

  if (rtn == -1) {
    perror("Failed to get socket");
    exit(EXIT_FAILURE);
  }

  rtn = listen(s, 10);

  if (rtn == -1) {
    perror("Failed to listen on socket");
    exit(EXIT_FAILURE);
  }

  incoming_len = sizeof(addr);
  memset(&addr, 0, sizeof(addr));

  incoming_s = accept(s, (struct sockaddr *)&addr, &incoming_len);

  if (incoming_s == -1) {
    perror("Failed to accept incoming connection");
    exit(EXIT_FAILURE);
  }

  printf("Accepted incoming connection\n");

  for (;;) {
    ssize_t len = read(incoming_s, buff, BUF_SIZE);

    /* read returns -1 on error. Don't want to index an array with -1! */
    if (len < 0) {
      fprintf(stderr, "Failed to read network data\n");
    }
    else if (len == 0) {
      fprintf(stderr, "No response data read\n");
    }
    else {
      buff[len] = '\0';
      printf("client says : %s", buff);
      printf("speak ");
    }

    /*gets(buff);*/ /* gets is BAD!!! */
    if (fgets(buff, BUF_SIZE, stdin) == NULL) {
      fprintf(stderr, "Failed to read input\n");
      exit(EXIT_FAILURE);
    }

    len = write(incoming_s, buff, strlen(buff));

    if (len == -1) {
      perror("Failed to write\n");
      exit(EXIT_FAILURE);
    }

  }

  return 0;
}

Client Portion:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

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

#define BUF_SIZE 500
#define PORT 10122

int main(void) {
  int s;
  int rtn;
  char buff[BUF_SIZE];
  struct sockaddr_in addr;

  puts("Entering program");

  s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  if (s == -1) {
    perror("Failed to get socket");
    exit(EXIT_FAILURE);
  }

  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = INADDR_ANY;
  addr.sin_port = htons(PORT);

  rtn = connect(s, (struct sockaddr * )&addr, sizeof(addr) );

  if (rtn == -1) {
    perror("Failed to connect to server");
    exit(EXIT_FAILURE);
  }

  for(;;) {
    ssize_t len;
    printf("speak ");
    fflush(stdout);

    /*gets(buff);*/ /* gets is BAD!!! */
    if (fgets(buff, BUF_SIZE, stdin) == NULL) {
      fprintf(stderr, "Failed to read input\n");
      exit(EXIT_FAILURE);
    }

    len = write(s, buff, strlen(buff));

    if (len == -1) {
      perror("Failed to write\n");
      exit(EXIT_FAILURE);
    }

    len = read(s, buff, BUF_SIZE);

    /* read returns -1 on error. Don't want to index an array with -1! */
    if (len < 0) {
      fprintf(stderr, "Failed to read network data\n");
    }
    else if (len == 0) {
      fprintf(stderr, "No response data read\n");
    }
    else {
      buff[len] = '\0';
      printf("server says : %s\n", buff);
    }
  }

  return 0;
}

Namaste,
-Ray-

Edited 5 Years Ago by Xytheron: n/a

I forgot to include instructions on how it works...
To start the server type PTCServer <Number_of_Threads> <Port_Number>
and then to start the client type TTCClient <Server_Host> <Server_Port_Number>

The problem is that I want to be able to have my friends join in and that will require that I keep all the clients stored and then cycle through the clients sending the message to each of them but I'm not sure how to do that at this point in my class. I know it's a bit ahead of where we are but I thought it would be fun to try it out and would be pretty cool!

thanks again for the help!

Edited 5 Years Ago by Xytheron: n/a

Is this really that hard? Not in a sarcastic way, just is this really that tough of a thing to do that people aren't responding because it's more than a little work? If so then I guess it'd be good to know that I'm kinda out of my depth and I should just use the talk function(which doesn't happen to be enabled on our machines)

Namaste,
-Ray-

This article has been dead for over six months. Start a new discussion instead.