bldzrjie
bldzrjie

Reputation: 13

Troubles creating a Server/Client TCP/IP Program

I have to create a TCP/IP server/client socket program where both the server and client have to be in the same .c file. Below is my code where if there are no command line arguments entered then a server is created and waits for another process to initiate a connection. If there's one command line argument entered (IP address) then the process takes on a client role and connects to the other process executing at the specificed IP address. I'm just using localhost.

When I run the program with an ip address (./game localhost) I get

~/Desktop/a5 20 $ ./game localhost
ERROR connecting: Connection refused

When I run the program with no ip address (./game) I get a segfault

~/Desktop/a5 19 $ ./game
Segmentation fault (core dumped)

Any help as to what I'm doing wrong would be greatly appreciated!

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

#define h_addr h_addr_list[0]

void error(char *msg) {
  perror(msg);
  exit(1);
}

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

  int sockfd, newsockfd, portno, clilen, sockfd2, portno2, n, n2;
  char buffer[256];
  char buffer2[256];
  struct sockaddr_in serv_addr, cli_addr, serv_addr2;
  struct hostent *server;

  portno = 4547;

  if (argc == 1) {
    sockfd2 = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd2 < 0) {
      error("ERROR opening socket");
    }

    server = gethostbyname(argv[1]);

    if (server == NULL) {
      fprintf(stderr,"ERROR, no such host\n");
      exit(0);
    }

    bzero((char *) &serv_addr2, sizeof(serv_addr2));
    serv_addr2.sin_family = AF_INET;

    bcopy((char *)server->h_addr,(char *)&serv_addr2.sin_addr.s_addr,server->h_length);

    serv_addr2.sin_port = htons(portno);

    if (connect(sockfd2,(struct sockaddr *)&serv_addr2,sizeof(serv_addr2)) < 0) {
      error("ERROR connecting");
    }

    printf("Please enter the message: ");
    bzero(buffer2,256);
    fgets(buffer2,255,stdin);
    n2 = write(sockfd2,buffer2,strlen(buffer2));

    if (n2 < 0) {
      error("ERROR writing to socket");
    }

    printf("%s\n",buffer2);
  }

  else if (argc == 0) {

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    if (sockfd < 0) {
      error("ERROR opening socket");
    }

    bzero((char *) &serv_addr, sizeof(serv_addr));

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);

    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");
    }

    bzero(buffer,256);

    n = read(newsockfd,buffer,255);

    if (n < 0) {
      error("ERROR reading from socket");
    }  

    printf("Here is the message: %s\n",buffer);

    n = write(newsockfd,"I got your message", 18);

    if (n < 0) {
      error("ERROR writing to socket");
    }
  }

  return 0;
}

Upvotes: 0

Views: 98

Answers (1)

cadaniluk
cadaniluk

Reputation: 15229

Usually argv[0] is a pointer to the command the executable was executed with. That means argc is always at least 1.
Increment the checks for argc like

if (argc == 1)

by one, so the above if clause changes to

if (argc == 2)

This is the reason for your segmentation fault because argv[1] passed to gethostbyname doesn't point to an argument if argc == 1 but contains NULL as the standard mandates that argv[argc] == NULL.


Note that this goes for the common systems. It is not defined in the C standard but in the POSIX standard, AFAIK.

Upvotes: 2

Related Questions