繁体   English   中英

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

[英]I'm trying to connect multiple clients with this server, but the code doesn't seem to work>

//////////////////////////  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() 函数并且没有使用多线程来同时拥有多个客户端。 服务器能够返回端口号、地址和套接字,但它们不是正确的。 地址结果为空。 顺便说一句,无论客户端发送什么,服务器都应该将其发送回客户端。 出于某种原因,当我尝试使用命令提示符将此代码编译为可执行文件时,我现在正面临另一个问题。 由于某种原因创建的文件根本没有打开。 我点击它,它打开一秒钟,就是这样。

当您从客户端读取时,无论它是哪个客户端,您总是将回复发送回clientfd (这是最后一个连接的客户端)而不是sd (您收到消息的客户端)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM