c - 我收到不支持的操作错误

标签 c sockets

我在虚拟盒子上使用 Ubuntu,我有一个使用服务器和客户端的虚拟刽子手游戏。多个客户端可以一次连接到服务器,但是当游戏结束时,这是服务器上出现的错误“接受连接:不支持操作”

这是我的代码

#include <sys/types.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <syslog.h>
#include <signal.h>
#include <errno.h>
#include <string.h>

extern time_t time ();

int maxlives = 12;
char *word [] = {
# include "words"
};
# define NUM_OF_WORDS (sizeof (word) / sizeof (word [0]))
# define MAXLEN 80 /* Maximum size in the world of Any string */
# define HANGMAN_TCP_PORT 1066

int main ()
{
int sock, fd, client_len;
pid_t pid;
struct sockaddr_in server, client;

srand ((int) time ((long *) 0)); /* randomize the seed */

sock = socket (AF_INET, SOCK_STREAM, 0);//0 or IPPROTO_TCP
if (sock <0) { //This error checking is the code Stevens wraps in his Socket Function etc
    perror ("creating stream socket");
    exit (1);
}

server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(HANGMAN_TCP_PORT);

if (bind(sock, (struct sockaddr *) & server, sizeof(server)) <0) {
    perror ("binding socket");
    exit (2);
}

listen (sock, 5);

while (1) {
    client_len = sizeof (client);
    if ((fd = accept (sock, (struct sockaddr *) &client, &client_len)) <0) 
            {
        perror ("accepting connection");
        exit (3);
    }
    else
    {   
        //make a child using fork();
        // fork();
        pid = fork();

    //if id == 0, it is child           
    if(pid ==0)
        {
        //close the listening port, play hangman
          close(sock);
              play_hangman (fd, fd);            

        close(fd);
    }
    //else, it is parent, ignore child and guest, listen for more guests to make more children with
       else {
    close (fd);
  }
   }
  }
 close(fd);
  }

 /* ---------------- Play_hangman () ---------------------*/

play_hangman (int in, int out)
{
   char * whole_word, part_word [MAXLEN],
guess[MAXLEN], outbuf [MAXLEN];

int lives = maxlives;
int game_state = 'I';//I = Incomplete
int i, good_guess, word_length;
char hostname[MAXLEN];

gethostname (hostname, MAXLEN);
sprintf(outbuf, "Playing hangman on host% s: \n \n", hostname);
write(out, outbuf, strlen (outbuf));

/* Pick a word at random from the list */
whole_word = word[rand() % NUM_OF_WORDS];
word_length = strlen(whole_word);
syslog (LOG_USER | LOG_INFO, "server chose hangman word %s", whole_word);

/* No letters are guessed Initially */
for (i = 0; i <word_length; i++)
    part_word[i]='-';

part_word[i] = '\0';

sprintf (outbuf, "%s %d \n", part_word, lives);
write (out, outbuf, strlen(outbuf));

while (game_state == 'I')
/* Get a letter from player guess */
{
    while (read (in, guess, MAXLEN) <0) {
        if (errno != EINTR)
            exit (4);
        printf ("re-read the startin \n");
        } /* Re-start read () if interrupted by signal */
good_guess = 0;
for (i = 0; i <word_length; i++) {
    if (guess [0] == whole_word [i]) {
    good_guess = 1;
    part_word [i] = whole_word [i];
    }
}
if (! good_guess) lives--;
if (strcmp (whole_word, part_word) == 0)
    game_state = 'W'; /* W ==> User Won */
else if (lives == 0) {
    game_state = 'L'; /* L ==> User Lost */
    strcpy (part_word, whole_word); /* User Show the word */
}
sprintf (outbuf, "%s %d \n", part_word, lives);
write (out, outbuf, strlen (outbuf));
}
}

我发现问题好像出在这里

//这里

while (1) {
    client_len = sizeof (client);
    if ((fd = accept (sock, (struct sockaddr *) &client, &client_len)) <0) 
            {

         perror ("accepting connection"); 
        exit (3);
    }
    else
    {   
        //make a child using fork();
        // fork();
        pid = fork();

//这里

但我不知道哪里出了问题,也不知道如何解决这个错误。

最佳答案

当游戏结束时,您应该终止子进程。但是您正在尝试使用已经关闭的 sock 描述符迭代 accept() 循环:

if(pid == 0)
{
    //close the listening port, play hangman
    close(sock);
    play_hangman (fd, fd);            
    // child has done its job, terminate immediately
    _Exit(0);
}
//else, it is parent, ignore child and guest, listen for more guests to make more children with
else {
    close (fd);
}

可能当您的 child 正在运行 play_hangman() 时,存储在 sock 中的值可能会被其他文件重用,因为我们之前已经关闭了该描述符。那个新文件绝对不是监听套接字。结果 accept() 失败并显示 Operation not supported

关于c - 我收到不支持的操作错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40629051/

相关文章:

java - 如何根据 Java 中的 URLConnection 为 BufferedReader 设置超时?

java - JAVA 上的 TCP 套接字 - 任何字节 >= 128 被接收为 65533

c - 制作 : *** No rule to make target

c - C 中二维数组的内存映射

c - 从不兼容的指针类型获取初始化上下文

c - 无法在 C 中将 'y1' 用作浮点变量

c# - 处理阻塞 .NET 套接字的超时

c - UDP客户端没有bind()接收不到数据

java - 通过套接字发送对象,但不同语言的客户端,如何使对象序列化?

c - 单链表头尾法?