创建服务器/客户端TCP / IP程序的麻烦

时间:2015-12-04 08:25:37

标签: c sockets tcp ip

我必须创建一个TCP / IP服务器/客户端套接字程序,其中服务器和客户端必须位于相同的.c文件中。下面是我的代码,如果没有输入命令行参数,则创建服务器并等待另一个进程启动连接。如果输入了一个命令行参数(IP地址),则该进程将接受客户端角色并连接到在特定IP地址执行的其他进程。我只是使用localhost。

当我使用ip地址(./game localhost)运行程序时,我得到了

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

当我运行没有ip地址的程序(./game)时,我得到一个段错误

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

对于我做错的任何帮助都将不胜感激!

#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;
}

1 个答案:

答案 0 :(得分:2)

通常argv[0]是指向执行可执行文件的命令的指针。这意味着argc 始终至少为1
增加对argc的检查,如

if (argc == 1)

一,所以上面的if子句改为

if (argc == 2)

这是您的细分错误的原因,因为传递给argv[1]的{​​{1}}并未指向参数gethostbyname但是包含argc == 1作为标准要求NULL

请注意,这适用于常见系统。 未在C标准中定义,但在POSIX标准中,AFAIK。