Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
创建服务器/客户端TCP/IP程序时出现问题_C_Sockets_Tcp_Ip - Fatal编程技术网

创建服务器/客户端TCP/IP程序时出现问题

创建服务器/客户端TCP/IP程序时出现问题,c,sockets,tcp,ip,C,Sockets,Tcp,Ip,我必须创建一个TCP/IP服务器/客户端套接字程序,其中服务器和客户端必须位于同一个.c文件中。下面是我的代码,如果没有输入命令行参数,那么将创建一个服务器,并等待另一个进程启动连接。如果输入了一个命令行参数(IP地址),则该进程将承担客户端角色,并连接到在指定IP地址执行的另一个进程。我只是在用localhost 当我使用ip地址(./game localhost)运行程序时,我得到 当我在没有ip地址(/游戏)的情况下运行程序时,我得到一个segfault ~/Desktop/a5 19 $

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

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

当我在没有ip地址(/游戏)的情况下运行程序时,我得到一个segfault

~/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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义h_地址h_地址列表[0]
无效错误(字符*消息){
佩罗尔(味精);
出口(1);
}
int main(int argc,char*argv[]){
int sockfd、newsockfd、端口号、clilen、sockfd2、端口号2、n、n2;
字符缓冲区[256];
字符缓冲区2[256];
serv_addr中的结构sockaddr_、cli_addr、serv_addr2;
结构主机*服务器;
portno=4547;
如果(argc==1){
sockfd2=套接字(AF_INET,SOCK_STREAM,0);
if(sockfd2<0){
错误(“打开套接字时出错”);
}
server=gethostbyname(argv[1]);
如果(服务器==NULL){
fprintf(stderr,“错误,没有这样的主机\n”);
出口(0);
}
bzero((char*)和serv_addr2,sizeof(serv_addr2));
serv_addr2.sin_family=AF_INET;
b复制((char*)服务器->h_地址,(char*)和服务地址r2.sin_地址.s_地址,服务器->h_长度);
serv_addr2.sin_port=htons(端口号);
if(connect(sockfd2,(struct sockaddr*)&serv_addr2,sizeof(serv_addr2))<0){
错误(“连接错误”);
}
printf(“请输入消息:”);
bzero(2256);
fgets(buffer2255,stdin);
n2=写入(sockfd2、buffer2、strlen(buffer2));
if(n2<0){
错误(“写入套接字时出错”);
}
printf(“%s\n”,buffer2);
}
else if(argc==0){
sockfd=套接字(AF_INET,SOCK_STREAM,0);
if(sockfd<0){
错误(“打开套接字时出错”);
}
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(端口号);
if(bind(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))<0){
错误(“绑定错误”);
}
听(sockfd,5);
clilen=sizeof(cli_addr);
newsockfd=accept(sockfd,(struct sockaddr*)&cli\u addr,&clilen);
if(newsockfd<0){
错误(“接受错误”);
}
b0(缓冲器,256);
n=读取(newsockfd,缓冲区,255);
if(n<0){
错误(“从套接字读取错误”);
}  
printf(“这是消息:%s\n”,缓冲区);
n=写(newsockfd,“我收到你的消息”,18);
if(n<0){
错误(“写入套接字时出错”);
}
}
返回0;
}

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

if (argc == 1)
因此,上面的
if
子句更改为

if (argc == 2)
这就是分段错误的原因,因为传递给
gethostbyname
argv[1]
没有指向
argc==1
的参数,而是包含
NULL
,因为标准要求
argv[argc]==NULL



请注意,这适用于通用系统。它在C标准中没有定义,但在POSIX标准中,AFAIK中没有定义。

您确实有一台服务器在本地主机上侦听:4547?至于崩溃,请在调试器中运行以捕获它,并查看它发生在代码中的何处。Cargo-cult'bzero(buffer,256);':(@MartinJames,每次我看到这一点,我都会伸手去拿我的枪。谁告诉他们的?他们为什么要重新复制它?@SergeyA我最近发现,如果你在谷歌上搜索“C TCP服务器客户端”,最上面的条目有以下垃圾:
if (argc == 2)