多任务网络编程

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <sys/socket.h>
  5 #include <netinet/in.h>
  6 #include <arpa/inet.h>
  7 #include "link.h"
  8 
  9 #define PORT 8888
 10 int main(void)
 11 {
 12     int sock_fd;
 13     int conn_fd;
 14     struct sockaddr_in sin;//server port
 15     struct sockaddr_in cin;//client port
 16     socklen_t len;
 17     int ret;
 18     char buf[100];
 19     fd_set read_fds;
 20     int max_fd;
 21     plink H;        //linklist for accept
 22     plink p;
 23 
 24     init_link(&H); //linlist initilized
 25     sock_fd = socket(AF_INET, SOCK_STREAM, 0); //creat soket    
 26     if(sock_fd < 0)
 27     {
 28     perror("socket");
 29     exit(1);
 30     }
 31     sin.sin_family = AF_INET;   //fill struct for bind
 32     sin.sin_port = htons(PORT);
 33     inet_pton(AF_INET, "192.168.7.2", (void *)&sin.sin_addr.s_addr);
 34     ret = bind(sock_fd, (struct sockaddr *)&sin, sizeof(sin));
 35     if(ret < 0)
 36     {
 37     perror("socket");
 38     exit(1);
 39     }
 40     listen(sock_fd, 10);
 41     len = sizeof(cin);
 42     printf("the server  is listening...............\n");
 43 
 44     max_fd = sock_fd;
 45     while(1)
 46     {
 47     FD_ZERO(&read_fds);//clear all the num
 48     FD_SET(sock_fd, &read_fds);//set sock_fd  1
 49     if(!is_empty(H))
 50     {
 51         p = H->next;
 52         while(p != NULL)
 53         {
 54         FD_SET(p->conn_fd, &read_fds);
 55         p = p->next;
 56         }
 57     }
 58 
 59     ret = select(max_fd + 1, &read_fds, NULL, NULL, NULL);
 60     if(ret < 0)
 61     {
 62         perror("select");
 63         exit(1);
 64     }
 65     if(ret == 0)
 66     {
 67         printf("time out!\n");
 68     }
 69 
 70     if(FD_ISSET(sock_fd, &read_fds))// check the num
 71     {
 72        conn_fd = accept(sock_fd, (struct sockaddr *)&cin, &len);
 73         if(conn_fd < 0)
 74         {
 75         perror("accept");
 76         exit(1);
 77         }
 78         link_insert(H, conn_fd);//insert conn_fd  into list
 79         max_fd = max_fd > conn_fd?max_fd:conn_fd;//for the largest num
 80         printf("IP  %s   is connecting \n", inet_ntoa(cin.sin_addr));
 81     }
 82 
 83 
 84     if(!is_empty(H))
 85     {
 86         p = H->next;
 87         while(p != NULL)
 88         {
 89         if(FD_ISSET(p->conn_fd, &read_fds))
 90         {
 91  92             {
 93             ret = read(p->conn_fd, buf, 20);
 94             if(ret == 0)
 95             {
 96                 printf("IP  %s is leaving \n", inet_ntoa(cin.sin_addr));
 97                 p = link_delete(H,p->conn_fd);
 98             }
 99             printf("read: %s", buf);
100             }
101 
102         }
103         p = p->next;
104         }
105         show_link(H);
106     }
107     }
108     close(sock_fd);
109     close(conn_fd);
110 
111     return 0;
112 
113 }

/*************************************************************************************************/

#include "link.h"

void init_link(linknode **pH)
{
    *pH = (plink)malloc(sizeof(linknode));
    if(NULL == *pH)
    {
        perror("malloc");
        exit(1);
    }
    (*pH)->next = NULL;
}

plink getlist(plink pH, int n)
{
    plink p = pH;
    int j = 0;
    while(p->next != NULL && j<n)
    {
        p = p->next;
        j++;
    }
    if(j == n)
        return p;
    else
        return NULL;
}
void link_insert(plink pH, int  x)
{
    plink p;
    plink new;
    plink r = pH;

    p = pH->next;
    while(p != NULL)
    {
        r = p;
        p = p->next;
    }
    new = (plink)malloc(sizeof(linknode));
    new->conn_fd = x;
    new->next = NULL;
    r->next = new;
}

plink getval(plink pH, int x)
{
    plink p = pH->next;
    if(p->next == NULL)
        return pH;
    while(p && p->next->conn_fd != x)
    {
        p = p->next;
    }
    if(p != NULL)
        return p;
    else
        return NULL;
}
plink link_delete(plink pH, int x)
{
    plink p;
    plink q;
    p = getval(pH, x);
    if(p != NULL)
    {
        if(pH->next == p)
        {
    //        pH->next = NULL;
    //        free(p);
        }
        q = p->next;
        p->next = q->next;
        free(q);
    }

    return p; 

}

void invert(plink pH)
{
    plink q;
    plink p = pH->next;
    pH->next = NULL;
    while(p != NULL)
    {
        q = p;
        p = p->next;
        q->next = pH->next;
        pH->next = q;
    }
}

bool is_empty(plink pH)
{
    if(pH->next == NULL)
        return true;
    else
        return false;
}

void show_link(plink H)
{
    int count = 0;
    plink p = H->next;
    while(p != NULL)
    {
    //    printf("%d\t", p->conn_fd);
        count++;
        p = p->next;
    }
    printf("there are still %d guest online\n", count);
}

/********************************************************************************************/

#ifndef _LINK_H
#define _LINK_H

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>


typedef struct node
{
    int  conn_fd;
    struct node *next;
}linknode, *plink;

void init_link(linknode **pH);
plink getlist(plink pH, int n);
void link_insert(plink pH, int x);
plink getval(plink pH, int x);
plink link_delete(plink pH, int x);
void invert(plink pH);
void show_link(plink H);

#endif

/*****************************************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 8888
int main(void)
{
    int sock_fd;
    int conn_fd;
    struct sockaddr_in sin;
    socklen_t len;
    int ret;
    char buf[100];

    
    sock_fd = socket(AF_INET, SOCK_STREAM, 0);    
    if(sock_fd < 0)
    {
    perror("socket");
    exit(1);
    }
        sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT);
    inet_aton("192.168.7.2", &sin.sin_addr);

    ret = connect(sock_fd, (struct sockaddr *)&sin, sizeof(sin));
    if(ret < 0)
    {
    perror("accept");
    exit(1);
    }

        while(1)
    {
    fgets(buf, 1024, stdin);
    write(sock_fd, buf, 20);
    }

    close(sock_fd);
    close(conn_fd);
    return 0;

}

 

程序使用slect实现多路IO的监控,下面介绍整体设计思路:

1.服务器端socket后等待accept的三次握手操作

2.握手成功后通过建立链表的形式将每次监听获得的链接存在链表的结构体中

3.服务端再确认是否有链接数据传送,有则把数据读出来

 

 

posted @ 2014-04-02 23:05  小小梦想不停追  阅读(181)  评论(0)    收藏  举报