/*

WINDOWS,SERVER,SELECT(RECV),BASIC(SEND)

*/

 

#include  <winsock2.h>
#include  <stdio.h>
#include  <fcntl.h>
#include  <stdlib.h>
#include  <string.h>

#define MAXLINE 4096
#define MAX_SOCK 64

#define bzero(b,len) (memset(b,0,len))
#define bcopy(b1,b2,len) (memcpy(b1,b2,len))

char *escapechar = "exit";
char send_calc_msg[MAXLINE+1];

//EXTERN LINK VARIABLE
char input[MAXLINE+1];

int maxfd;
int g_num_chat = 0;
int client_s[MAX_SOCK];


//STATIC LINK
static int getmax(int);
static void removeclient(int);
static int getdottedipaddr(int sd, struct sockaddr_in *addr);

int main(int argc, char *argv[]) 
{
    char rline[MAXLINE+1];
    int ii, kk, nn;
    int client_fd, clilen, rc;

    fd_set read_fds;
    WSADATA wsadata;
    SOCKET hservsock;
    SOCKADDR_IN client_addr, server_addr;

    if (argc != 2) {
        printf("usage : %s port\n", argv[0]);
        return(-1);
    }

if(WSAStartup(MAKEWORD(2,2), &wsadata) != 0)
    {
        return(-9);
    }

    hservsock=socket(PF_INET, SOCK_STREAM, 0);
    if(hservsock==INVALID_SOCKET)
    {
        return(-8);
    }

    bzero((char *)&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(atoi(argv[1]));

    if (bind(hservsock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        return(-3);
    }
    listen(hservsock, 5); /* backlog = 5 */
    maxfd = hservsock + 1;

for(;;)
    {
        FD_ZERO(&read_fds);
        FD_SET(hservsock, &read_fds);
        for (ii=0; ii < g_num_chat; ii++)
        {
            FD_SET(client_s[ii], &read_fds);
        }
        maxfd = getmax(hservsock) + 1;

        if (select(maxfd, &read_fds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) 
        {
            printf("server: select error.\n");
            break;
        }

        if (FD_ISSET(hservsock, &read_fds)) 
        {
            clilen = sizeof(client_addr);
            client_fd = accept(hservsock, (struct sockaddr *)&client_addr, &clilen);
            if (client_fd == -1) 
            {
                printf("server: accept error\n");
                break;
            }
            client_s[g_num_chat] = client_fd;
            g_num_chat++;
        }

        for (ii=0; ii<g_num_chat; ii++) 
        {
            if (FD_ISSET(client_s[ii], &read_fds)) 
            {
                if ((nn = recv(client_s[ii], rline, MAXLINE, 0)) <= 0) 
                {
                    removeclient(ii); /* abrupt exit *//* abrupt exit *//* abrupt exit *//* abrupt exit */
                    continue;
                }
                rline[nn] = 0x00;

                for (kk=0; kk<g_num_chat; kk++)
                {
                    send(client_s[kk], rline, nn, 0);
                    printf("[%.5d][%d]%s", kk, client_s[ii], rline);
                }
            }
        }
    } /* while */

    rc = WSACleanup();
    if(rc == WSANOTINITIALISED)
    {
        printf(">>error::A successful WSAStartup call must occur before using this function.\n");
    }
    else if(rc == WSAENETDOWN)
    {
        printf(">>error::The network subsystem has failed.\n");
    }
    else if(rc == WSAEINPROGRESS)
    {
        printf(">>error::A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.\n");
    }
    closesocket(hservsock);
}

void removeclient(int indx) 
{
    struct sockaddr_in client_addr;

    if (getdottedipaddr(client_s[indx], &client_addr) > -1)
    {
        printf("\nserver>>removeclient>>1 number expired!!(IP: %s).", inet_ntoa(client_addr.sin_addr));
    }
    else
    {
        printf("\nserver>>removeclient>>1 number expired!!.");
    }

    closesocket(client_s[indx]);

    if (indx != g_num_chat-1)
    {
        client_s[indx] = client_s[g_num_chat-1];
    }

    g_num_chat--;
    printf("\nserver>>removeclient>>now number = %d\n", g_num_chat);
}

int getmax(int k) 
{
    int max = k;
    int r;

    for (r=0; r < g_num_chat; r++)
    {
        if (client_s[r] > max) max = client_s[r];
    }
    return max;
}

int getdottedipaddr(int sd, struct sockaddr_in *addr) 
{
    struct sockaddr_in client_addr;
    int len, r;

    len = sizeof(client_addr);
    if ((r = getpeername(sd, (struct sockaddr *)&client_addr, &len)) == 0)
    {
        *addr = client_addr;
    }
    return r;
}

+ Recent posts