c - 在 C 中用 select() 读取然后写入?

标签 c sockets tcp

我如何从某个客户端读取输入数据,然后使用该数据进行计算,然后将结果写回客户端。我现在所拥有的将获取输入数据,但是当我写回我的客户端程序时似乎没有得到任何东西。这就是我现在所拥有的。它不是整个代码,但任何 undefined variable 都应该有明确的含义。我需要做一个 writefd 并检查吗?我需要确保它返回到正确的客户端,但不明白如何执行此操作?

 while(TRUE) 
{
    FD_ZERO(&readfds);
    //add master socket to set
    FD_SET(master_socket, &readfds);
    max_sd = master_socket;

    //add child sockets to set
    for ( i = 0 ; i < max_clients ; i++) 
    {
        //socket descriptor
        sd = client_socket[i];
        if(sd > 0)
            FD_SET( sd , &readfds);
        if(sd > max_sd)
            max_sd = sd;
    }
    //waiting for activity
    activity = select( max_sd + 1 , &readfds , &writefds, NULL , NULL);    
    if ((activity < 0) && (errno!=EINTR)) 
    {
        printf("select error");
    }

if (FD_ISSET(master_socket, &readfds)) 
    {

        recv(new_socket,buffer,1025,0);
        printf(buffer); // i recieve input data, though it isn't correct, but at least something is recieved. 
        //add new socket to array of sockets

        for (i = 0; i < max_clients; i++) 
        {
            //if position is empty
            if( client_socket[i] == 0 )
            {
                client_socket[i] = new_socket;
                printf("Adding to list of sockets as %d\n" , i);
                send(new_socket, "here", strlen("here"),0);
                break;
            }
        }
    }

最佳答案

master_socket被标记为可读时,您将在new_socket上调用recv()。假设 master_socket 是您的监听服务器套接字,您需要调用 accept() 来接收新客户端。不要调用 recv() 除非 select() 告诉您特定客户端可读,然后从该客户端读取。

尝试更多类似这样的事情:

for (i = 0; i < max_clients; ++i)
    client_socket[i] = -1;

...

while (TRUE) 
{
    FD_ZERO(&readfds);

    //add master socket to set
    FD_SET(master_socket, &readfds);
    max_sd = master_socket;

    //add child sockets to set
    for (i = 0; i < max_clients; ++i)
    {
        //socket descriptor
        sd = client_socket[i];
        if (sd > -1)
        {
            FD_SET(sd, &readfds);
            if (sd > max_sd)
                max_sd = sd;
        }
    }

    //waiting for activity
    activity = select(max_sd + 1, &readfds, NULL, NULL, NULL);
    if (activity < 0)
    {
        if (errno != EINTR)
            printf("select error");
    }
    else
    {
        //check master socket to accept from
        if (FD_ISSET(master_socket, &readfds)) 
        {
            new_socket = accept(master_socket, NULL, NULL);
            if (new_socket < 0)
            {
                printf("accept error");
            }
            else
            {
                //add new socket to array of sockets
                for (i = 0; i < max_clients; ++i)
                {
                    //if position is empty
                    if (client_socket[i] == -1)
                    {
                        client_socket[i] = new_socket;
                        printf("Adding to list of sockets as %d\n" , i);
                        send(new_socket, "here", strlen("here"), 0);
                        new_socket = -1;
                        break;
                    }
                }

                // close new socket if no room for it
                if (new_socket > -1)
                    close(new_socket);
            }
        }

        //check child sockets to read from
        for (i = 0 ; i < max_clients; ++i) 
        {
            sd = client_socket[i];
            if (sd > -1)
            {
                if (FD_ISSET(sd, &readfds)) 
                {
                    len = recv(sd, buffer, 1025, 0);
                    if (len > 0)
                    {
                        // data received
                        buffer[len] = 0; // make sure it is null terminated
                        printf("data: %s", buffer);
                        // or: printf("data: %.*s", len, buffer);
                    }
                    else
                    {
                        if (len == 0)
                            printf("disconnected");
                        else
                            printf("recv error");

                        printf("Removing from list of sockets at %d\n", i);
                        close(sd);
                        client_socket[i] = -1;
                    }
                }
            }
        }
    }

关于c - 在 C 中用 select() 读取然后写入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34212803/

相关文章:

c# - 使连接的套接字在.BeginReceive 之后立即接受新消息?

套接字 TCP 服务器

c++ - 使用winsock api同时打开tcp连接

c - 为什么当我试图获得 60 时 FPS 显示 30?

c# - 为什么在客户端拆分 TCP 消息不起作用?

C++ 包括 C 文件(未找到 typedef)

PHP 向 Node/Socket.IO 服务器发送消息

Tomcat 端口打开但应用程序无法加载

c、按位、逻辑表达式

c - 指向整数的指针数组