我正在尝试将多个客户端与此服务器连接,但是代码似乎不起作用>

时间:2019-12-02 15:09:56

标签: c sockets server

//////////////////////////  Server2.c ////////////////

#include<io.h>
#include<stdio.h>
#include<winsock2.h>
#include <ctype.h>
#include<string.h>
#include <sys/time.h>
#include <errno.h>



#define MY_PORT     8989 //defining the port for the socket
#define MAXBUF      256



int main(int argc , char *argv[])
{
    int a,i ;

    char str[MAXBUF];

    WSADATA wsa;
    SOCKET sockfd , clientfd;
    struct sockaddr_in self;
    int max_clients=30, client_socket[30],maxsd, sd,activ;
    char buffer[MAXBUF];
    char message[MAXBUF];

    /*set of socket descriptors will be in this */
    fd_set readfds;

    /*Initializing all client to zero */
     for (i = 0; i < max_clients; i++)
    {
        client_socket[i] = 0;
    }


    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        printf("Failed. Error Code : %d",WSAGetLastError());
        return 1;
    }

    printf("Initialised.\n");

    /*---create streaming socket---*/
    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
    {
        perror("Socket");
        exit(errno);
    }

        printf("Socket created.\n");

    {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }

    /*---initialize address/port structure---*/

    self.sin_family = AF_INET;
    self.sin_port = htons(MY_PORT);
    self.sin_addr.s_addr = INADDR_ANY;

    /*---assign a port number to the socket---*/
    if ( bind(sockfd, (struct sockaddr*)&self, sizeof(self)) != 0 )
    {
        perror("socket--bind");
        exit(errno);
    }
        puts("Bind done"); //binding completed
    /*---make it a "listening socket"---*/
    if ( listen(sockfd, 3) != 0 )
    {
        perror("socket--listen");
        exit(errno);
    }

        puts("Waiting for incoming connections...");

    /*---forever... ---*/

    while (1)
    {   struct sockaddr_in client_addr;
        int addrlen=sizeof(client_addr);

        /*Clearing the socket set we created before*/
        FD_ZERO(&readfds);

        /*adding the socket we created to set*/
        FD_SET(sockfd,&readfds);
        maxsd=sockfd;
        /*Now we add the child sockets to the set */
        for ( i = 0 ; i < max_clients ; i++)
        {
            //socket descriptor
            sd = client_socket[i];

            //if valid socket descriptor then add to read list
            if(sd > 0)
                FD_SET( sd , &readfds);

            //highest file descriptor number, need it for the select function
            if(sd > maxsd)
                maxsd = sd;
        }
        /*we wait for activity on any one of the sockets, this will wait forever as timeout is NULL*/
        activ=select(maxsd+1, &readfds,NULL,NULL,NULL);

        if ((activ < 0) && (errno!=EINTR))
        {
            printf("select error");
        }

        /* If there is any sort of activity on sockfd then it will be the socket that the server has to serve */
        if (FD_ISSET(sockfd,&readfds)){
            if (clientfd= accept(sockfd, (struct sockaddr*)&client_addr, &addrlen)<0)
                {
                perror("Accept");
                exit(EXIT_FAILURE);

                }

        /*telling the user of socket number, port and ip of client*/
        printf("Connected Client\nSocket fd is %d\nIP is :%s\nPort:%d\n",clientfd,self.sin_addr.s_addr, htons(self.sin_port));

        /*adding new socket to array of sockets */
        for (i=0; i<max_clients;i++)
        {
            if(client_socket[i]==0) //if element is empty
            {
                client_socket[i]=clientfd;
                break;
            }
        }
        }
        /*else there might be some Input?output operations on some other socket*/
        for (i = 0; i < max_clients; i++)
        {
            sd=client_socket[i];
            if (FD_ISSET( sd , &readfds))
            {
                if((read(sd,buffer,MAXBUF))==0)
                {
                    printf("DISCONNECTED");

               //Close the socket and mark as 0 in list for reuse
                    close( sd );
                    client_socket[i] = 0;
                }
                else
                {
                send(clientfd,buffer, recv(clientfd, buffer, MAXBUF, 0), 0);

                }
            }
        }
    }
        /*---close connection---*/
        //close(clientfd);


    /*---clean up (should never get here!)---*/
    //close(sockfd);
        WSACleanup();
    return 0;
}

该代码用于服务器,该服务器接受多个客户端,并能够确定在特定时间连接了哪个客户端。我使用了select()函数,并且没有使用多线程一次来拥有多个客户端。服务器能够返回端口号,地址和套接字,但是它们不是正确的。该地址原来为空。而且,无论客户端如何发送,服务器都应该发送回客户端。 由于某种原因,当我尝试将此代码编译为使用命令提示符的可执行文件时,我现在正面临另一个问题。由于某种原因创建的文件根本无法打开。我单击它,然后打开一秒钟,就是这样。

1 个答案:

答案 0 :(得分:0)

从客户那里读取信息时,无论是哪个客户端,都始终将答复发送回clientfd(这是连接的最后一个客户端),而不是sd(客户端您收到了消息)