Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.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
C中的套接字和服务器问题(名称或服务未知错误)_C_Sockets_Error Handling_Server_Client - Fatal编程技术网

C中的套接字和服务器问题(名称或服务未知错误)

C中的套接字和服务器问题(名称或服务未知错误),c,sockets,error-handling,server,client,C,Sockets,Error Handling,Server,Client,我正在开发一个客户机/服务器程序,该程序应该接受用户输入(两个整数),并允许用户计算这些输入以接收答案 当我运行我的程序时,连接到客户机或打开目录似乎有问题,我不确定这可能是什么问题。我对设置服务器和使用目录读写.txt文件是完全陌生的 下面是我认为可能是错误的代码部分,这些代码导致了我面临的问题,即程序要求连接到一个端口号(建议使用2000),因此我输入该端口号,然后什么也没有发生 // PURPOSE: To run the server by 'accept()'-ing clie

我正在开发一个客户机/服务器程序,该程序应该接受用户输入(两个整数),并允许用户计算这些输入以接收答案

当我运行我的程序时,连接到客户机或打开目录似乎有问题,我不确定这可能是什么问题。我对设置服务器和使用目录读写.txt文件是完全陌生的

下面是我认为可能是错误的代码部分,这些代码导致了我面临的问题,即程序要求连接到一个端口号(建议使用2000),因此我输入该端口号,然后什么也没有发生

  //  PURPOSE:  To run the server by 'accept()'-ing client requests from
//  'listenFd' and doing them.
void        doServer    (int        listenFd)

{
  /* Application validity check: */

  /* Server clients: */
  pthread_t     threadId;
  pthread_attr_t    threadAttr;
  int           threadCount = 0;
  int *iPtr;

  /* YOUR CODE HERE: */
  while(1)

  {

    /* Accept connection to client: */
    int connfd = accept(listenFd, NULL, NULL); //if I change this to getServerFileDescriptor (another function within the code, it will continuously loop through threadNumbers and do nothing as well).

    /* Malloc memory for two integers: */
    iPtr = (int *)calloc(2, sizeof(int));    

    /*Put file descriptor in the first space: */
    iPtr[0] = listenFd; // or just listenFd not sure

    /* put threadCount into the second space and increment: */
    iPtr[1] = threadCount++;

    /* Creates detached thread for handleClient and passes the address of iPtr */
    pthread_attr_init(&threadAttr);
    pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
    pthread_create(&threadId, &threadAttr, handleClient, (void*)iPtr);

    pthread_join(threadId, NULL); 
    pthread_attr_destroy(&threadAttr);


   }

}
void* handleClient(void* vPtr)
{
  /* Read command: */
  char  buffer[BUFFER_LEN];
  char  command;
  int   fileNum;
  char  text[BUFFER_LEN];
  int   shouldContinue  = 1;
  int threadNum;
  int fd;

  /* Cast void* vPtr back to an int */
  int *iPtr = (int *)vPtr;

  /* Assign file descriptor to a local value named 'fd'*/
  fd = iPtr[0];
  /* Assign thread number to local value named 'threadNum'*/
  threadNum = iPtr[1];

  free(iPtr);

  while  (shouldContinue)
  {
    memset(buffer,'\0',BUFFER_LEN);
    memset(text  ,'\0',BUFFER_LEN);

    read(fd,buffer,BUFFER_LEN);
    printf("Thread %d received: %s\n",threadNum,buffer);
    sscanf(buffer,"%c %d \"%[^\"]\"",&command,&fileNum,text);

    /* YOUR CODE HERE: */

    if(command == DIR_CMD_CHAR)
    {
        /* 1. Open the current directory (named "."). If an error occurs then just send STD_ERROR_MSG back to the client: */
        DIR* dirPtr = opendir(".");
        struct dirent* entryPtr;

        /* If error occurs send STD_ERROR_MSG to client: */
        if ((dirPtr = opendir (".")) == NULL) {
        {
          write(fd, STD_ERROR_MSG, sizeof(STD_ERROR_MSG));
          //return(EXIT_FAILURE);
        }

        /* Read as many entries that will fit into BUFFER_LEN 
        put as many entries into the buffer and send the buffer to client
        d_name=entryPtr into the bufffer using strcat_s,
        make sure buffer starts empty
        buffer[0]='\n';
        add new line char using stringcat "\n"
        make sure do not go over buffer lengh */

        if (dirPtr)
        {
          while ((entryPtr = readdir(dirPtr)) != NULL)
          {

            buffer[0]='\0';

            int i;
            int sizebuf = sizeof(buffer);

            for (i = 0; i < sizebuf; i++)
            {
            strcat(buffer,entryPtr->d_name);
            strcat(buffer,"\n");
            }
          }
        }
          /* 3. Close directory */
        closedir(dirPtr);
    }
它将()从客户端读取一行文本到缓冲区[],并将该行解析为命令字符、fileNum integer和引号分隔的文本[]字符串。(fileNum和text[]可以给定,也可以不给定,具体取决于命令的值。)

然后根据命令的值执行以下操作。除了QUIT\u CMD\u CHAR之外,我强烈建议对每个函数使用不同的函数

当函数结束时,让它执行以下操作:

 printf("Thread %d quitting.\n",threadNum);
  return(NULL);
command==DIR\u CMD\u CHAR(15分):

打开当前目录(名为“.”)。如果发生错误,只需将STD_error_MSG发送回客户端。 复制尽可能多的条目,将其放入长度为buffer_LEN的缓冲区中。请确保在每个条目后面加一个分隔的“\n”。 关闭目录

任何帮助将不胜感激,如果你需要完整的代码,我可以发送给你,如果这会有所帮助

编辑:这里有两个附加函数,一个名为getPortNum(),另一个名为getServerFileDescriptor(),用于处理接收端口号和为连接设置套接字的问题。此外,我还包括了main(),它利用了这些

//  PURPOSE:  To decide a port number, either from the command line arguments
//  'argc' and 'argv[]', or by asking the user.  Returns port number.
int     getPortNum  (int    argc,
                 char*  argv[]
                )
{
  //  I.  Application validity check:

  //  II.  Get listening socket:
  int   portNum;

  if  (argc >= 2)
    portNum = strtol(argv[1],NULL,0);
  else
  {
    char    buffer[BUFFER_LEN];

    printf("Port number to monopolize? ");
    fgets(buffer,BUFFER_LEN,stdin);
    portNum = strtol(buffer,NULL,0);
  }

  //  III.  Finished:  
  return(portNum);
}


//  PURPOSE:  To attempt to create and return a file-descriptor for listening
//  to the OS telling this server when a client process has connect()-ed
//  to 'port'.  Returns that file-descriptor, or 'ERROR_FD' on failure.
int     getServerFileDescriptor
                (int        port
                )
{
  //  I.  Application validity check:

  //  II.  Attempt to get socket file descriptor and bind it to 'port':
  //  II.A.  Create a socket
  int socketDescriptor = socket(AF_INET, // AF_INET domain
                    SOCK_STREAM, // Reliable TCP
                    0);

  if  (socketDescriptor < 0)
  {
    perror(THIS_PROGRAM_NAME);
    return(ERROR_FD);
  }

  //  II.B.  Attempt to bind 'socketDescriptor' to 'port':
  //  II.B.1.  We'll fill in this datastruct
  struct sockaddr_in socketInfo;

  //  II.B.2.  Fill socketInfo with 0's
  memset(&socketInfo,'\0',sizeof(socketInfo));

  //  II.B.3.  Use TCP/IP:
  socketInfo.sin_family = AF_INET;

  //  II.B.4.  Tell port in network endian with htons()
  socketInfo.sin_port = htons(port);

  //  II.B.5.  Allow machine to connect to this service
  socketInfo.sin_addr.s_addr = INADDR_ANY;

  //  II.B.6.  Try to bind socket with port and other specifications
  int status = bind(socketDescriptor, // from socket()
            (struct sockaddr*)&socketInfo,
            sizeof(socketInfo)
           );

  if  (status < 0)
  {
    perror(THIS_PROGRAM_NAME);
    return(ERROR_FD);
  }

  //  II.B.6.  Set OS queue length:
  listen(socketDescriptor,5);

  //  III.  Finished:
  return(socketDescriptor);
}


int     main        (int    argc,
                 char*  argv[]
                )
{
  //  I.  Application validity check:

  //  II.  Do server:
  int       port    = getPortNum(argc,argv);
  int         listenFd  = getServerFileDescriptor(port);
  int         status    = EXIT_FAILURE;

  if  (listenFd >= 0)
  {
    doServer(listenFd);
    close(listenFd);
    status  = EXIT_SUCCESS;
  }

  //  III.  Finished:
  return(status);
//目的:从命令行参数中确定端口号
//“argc”和“argv[]”,或询问用户。返回端口号。
int getPortNum(int argc,
字符*argv[]
)
{
//一、申请有效性检查:
//二、获取监听插座:
int-portNum;
如果(argc>=2)
portNum=strtol(argv[1],NULL,0);
其他的
{
字符缓冲区[buffer_LEN];
printf(“要垄断的端口号?”);
fgets(缓冲器、缓冲器、标准装置);
portNum=strtol(缓冲区,NULL,0);
}
//三、完成:
返回(portNum);
}
//目的:尝试创建并返回用于侦听的文件描述符
//当客户端进程已连接()时通知此服务器的操作系统
//到“端口”。返回该文件描述符,或失败时返回“ERROR\u FD”。
int getServerFileDescriptor
(内部端口)
)
{
//一、申请有效性检查:
//II.尝试获取套接字文件描述符并将其绑定到“端口”:
//II.A.创建一个插座
int-socketDescriptor=socket(AF_INET,//AF_INET域
SOCK\u流,//可靠的TCP
0);
if(socketDescriptor<0)
{
perror(该项目名称);
返回(错误\u FD);
}
//II.B.尝试将“socketDescriptor”绑定到“端口”:
//II.B.1.我们将填写此数据结构
socketInfo中的结构sockaddr_;
//II.B.2.用0填充socketInfo
memset(&socketInfo,'\0',sizeof(socketInfo));
//II.B.3.使用TCP/IP:
socketInfo.sin_family=AF_INET;
//II.B.4.用htons()在网络端告诉端口
socketInfo.sinu端口=htons(端口);
//II.B.5.允许机器连接到此服务
socketInfo.sinu addr.s\u addr=INADDR\u ANY;
//II.B.6.尝试将插座与端口和其他规格绑定
int status=bind(socketDescriptor,//来自socket()
(结构sockaddr*)和socketInfo,
sizeof(socketInfo)
);
如果(状态<0)
{
perror(该项目名称);
返回(错误\u FD);
}
//II.B.6.设置操作系统队列长度:
听(socketDescriptor,5);
//三、完成:
返回(socketDescriptor);
}
int main(int argc,
字符*argv[]
)
{
//一、申请有效性检查:
//二、做服务器:
int port=getPortNum(argc,argv);
int listenFd=getServerFileDescriptor(端口);
int status=退出故障;
如果(listenFd>=0)
{
doServer(listenFd);
关闭(listenFd);
状态=退出\成功;
}
//三、完成:
返回(状态);

Nevermind,我编辑了原始帖子并将其包括在内。您好,您能添加一个您在服务器和客户端之间实现的协议的描述吗?这是因为我看到这行代码可能有问题:
sscanf(缓冲区,“%c%d\”%[^\“]\”,&command,&fileNum,text);
//  PURPOSE:  To decide a port number, either from the command line arguments
//  'argc' and 'argv[]', or by asking the user.  Returns port number.
int     getPortNum  (int    argc,
                 char*  argv[]
                )
{
  //  I.  Application validity check:

  //  II.  Get listening socket:
  int   portNum;

  if  (argc >= 2)
    portNum = strtol(argv[1],NULL,0);
  else
  {
    char    buffer[BUFFER_LEN];

    printf("Port number to monopolize? ");
    fgets(buffer,BUFFER_LEN,stdin);
    portNum = strtol(buffer,NULL,0);
  }

  //  III.  Finished:  
  return(portNum);
}


//  PURPOSE:  To attempt to create and return a file-descriptor for listening
//  to the OS telling this server when a client process has connect()-ed
//  to 'port'.  Returns that file-descriptor, or 'ERROR_FD' on failure.
int     getServerFileDescriptor
                (int        port
                )
{
  //  I.  Application validity check:

  //  II.  Attempt to get socket file descriptor and bind it to 'port':
  //  II.A.  Create a socket
  int socketDescriptor = socket(AF_INET, // AF_INET domain
                    SOCK_STREAM, // Reliable TCP
                    0);

  if  (socketDescriptor < 0)
  {
    perror(THIS_PROGRAM_NAME);
    return(ERROR_FD);
  }

  //  II.B.  Attempt to bind 'socketDescriptor' to 'port':
  //  II.B.1.  We'll fill in this datastruct
  struct sockaddr_in socketInfo;

  //  II.B.2.  Fill socketInfo with 0's
  memset(&socketInfo,'\0',sizeof(socketInfo));

  //  II.B.3.  Use TCP/IP:
  socketInfo.sin_family = AF_INET;

  //  II.B.4.  Tell port in network endian with htons()
  socketInfo.sin_port = htons(port);

  //  II.B.5.  Allow machine to connect to this service
  socketInfo.sin_addr.s_addr = INADDR_ANY;

  //  II.B.6.  Try to bind socket with port and other specifications
  int status = bind(socketDescriptor, // from socket()
            (struct sockaddr*)&socketInfo,
            sizeof(socketInfo)
           );

  if  (status < 0)
  {
    perror(THIS_PROGRAM_NAME);
    return(ERROR_FD);
  }

  //  II.B.6.  Set OS queue length:
  listen(socketDescriptor,5);

  //  III.  Finished:
  return(socketDescriptor);
}


int     main        (int    argc,
                 char*  argv[]
                )
{
  //  I.  Application validity check:

  //  II.  Do server:
  int       port    = getPortNum(argc,argv);
  int         listenFd  = getServerFileDescriptor(port);
  int         status    = EXIT_FAILURE;

  if  (listenFd >= 0)
  {
    doServer(listenFd);
    close(listenFd);
    status  = EXIT_SUCCESS;
  }

  //  III.  Finished:
  return(status);