Chinaunix首页 | 论坛 | 博客
  • 博客访问: 59450
  • 博文数量: 20
  • 博客积分: 1653
  • 博客等级: 上尉
  • 技术积分: 156
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-22 12:55
文章分类
文章存档

2012年(8)

2011年(7)

2009年(5)

分类: LINUX

2009-12-29 20:01:35

功能比较简单,呵呵

服务端:
#include
#include
#include
#include
#include
#include
#include
#include

#include

int  sock; /* POSIX用int 来描述socket */

/* 多线程 TCP chat 服务器*/

#define MAX_USERS 30
/* 在线用户表,用下标表示对应的socket, online_user[8] =1 ,表示socket fd =8的socket 在线,=0表示下线*/
char online_user[MAX_USERS];
/* 用来保护在线用户表 online_user*/
pthread_mutex_t user_lock;


void exit_handler(int sig)
{
     close(sock);
     pthread_mutex_destroy(&user_lock);
         exit(0);
}


void * thread_fn(void *arg)
{
       char buffer[1024];
            int len,fd;
           
    
      int client_sock  = (int)arg;
     
      while(1)
              {
              /* 接收客户端数据*/
        len = recv(client_sock,buffer,sizeof(buffer)-1,0);
        if(len <=0)
                    {/* 通常是客户端已经关闭,从在线用户表把当前sock 清掉*/
           perror("recv");
         pthread_mutex_lock(&user_lock);
         online_user[client_sock] =0;
         pthread_mutex_unlock(&user_lock);
           break;
                    }
                   
                   
       buffer[len] =0;
       fprintf(stdout,"client:%s\n",buffer);
      
            
                 /* 把数据轮播到其它客户端*/    
       for(fd=0; fd< MAX_USERS ;fd++)
                   {
                         
          if((online_user[fd]  == 0) || (fd == client_sock))
                   continue;
                
       len = send(fd,buffer,len,0);
       if(len<= 0)
                   {
          perror("send");
         pthread_mutex_lock(&user_lock);
         online_user[client_sock] =0;
         pthread_mutex_unlock(&user_lock);
            break;
         
                     }
                   }
                }  
       close(client_sock);
}


int main(int argc,char * argv[])
{
  unsigned short port = 9000;
  socklen_t addrlen;
     struct sockaddr_in local_addr,client_addr;
     int client_sock,len,i;
     pthread_t th;
     const char * welcome_msg = "Welcom to Chat Server ,ver 1.0";
    
    
     signal(SIGINT,exit_handler);
   
   
   if(argc>1)
       {
             port = (unsigned short )atoi(argv[1]);
       }
      
       /* ------------第一步:创建socket ----------------*/
   sock = socket(PF_INET,SOCK_STREAM,0); /* ipv4,TCP,任意协议 */
   if(sock == -1)
       {
       perror("socket");
       exit(-1);
       }
      
       fprintf(stdout,"TCP char Server ,listen on %d,pit %d\n",port,getpid());
      
       /* ----------------第二步:绑定端口和网卡----------------------*/
   /* struct socketaddr_in 来指明这个SOCKET绑定在本地的哪一个的端口和哪一块网卡*/
     memset((void *)&local_addr,0,sizeof(local_addr));
    
    local_addr.sin_family = AF_INET ; /* ip v4 */
    local_addr.sin_port = htons(port); /* 端口号,要用网络序*/
   
       /* 可以取值 INADDR_ANY 表示这个socket可以这一台机器所有网卡上进行通信*/
       /* 如果本机一个某一个网卡的IP地址,表示只在这一块网卡进行通信*/
    local_addr.sin_addr.s_addr = INADDR_ANY;  /* INADDR_ANY = 0x0 */
   
       {
         int val = 1;
         setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof (val));
 
       }
      
   
    if(bind(sock,(struct sockaddr *)&local_addr,sizeof(local_addr)) == -1)
         {
        perror("bind");
        close(sock);
        exit(-2);
                 
         }
      
       /* ----------第三步:通知内核的PS开始侦听客户端请求-------------*/
    if(listen(sock,20) == -1)
        {
        perror("listen");
        close(sock);
        exit(-3);
              
        }
       
       
        /* 清空在线用户表,初始化锁*/
     for(i=0 ; i < MAX_USERS ;i++)
            online_user[i] =0;
      if(pthread_mutex_init(&user_lock,NULL)!=0)
               {
                        perror("mutex_init");
               }
       
        /*------ 第四步:接收客户端请求--------------------------*/
   while(1)
         {
         addrlen = sizeof(client_addr);
         client_sock = accept(sock,(struct sockaddr *)&client_addr,&addrlen);
         if(client_sock == -1)
                         {
             perror("accept");
             continue;
                         }
                        
         if(client_sock > MAX_USERS)
                        {
               char * close_msg = "online user too many";
              fprintf(stdout,"new socket %d is too big,max user is %d\n",client_sock,MAX_USERS);
               send(client_sock,close_msg,strlen(close_msg)+1,0);
              close(client_sock);
              continue;
                        }
                        
                         /* 发送欢迎信息*/
          send(client_sock,welcome_msg,strlen(welcome_msg)+1,0);
                        
                         /* 把新联接的socket加入到在线用户表当中*/
         pthread_mutex_lock(&user_lock);
         online_user[client_sock] =1;
         pthread_mutex_unlock(&user_lock);
        
                                    
         fprintf(stdout,"client addr %s,port %d,sock %d\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port),client_sock);
        
        pthread_create(&th,NULL,thread_fn,(void *)client_sock);
                  
         }
       
      
      
      
       exit_handler(100);
     
}

客户端:代码比较简单



阅读(2356) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~