聊天程序源码(服务器端)

转载自:http://blog.csdn.net/mafuli007/article/details/7232864

server.h //定义一些函数

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <sys/utsname.h>  
  5. #include <sys/types.h>  
  6. #include <sys/socket.h>  
  7. #include <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9. #include <netdb.h>  
  10. #include <unistd.h>  
  11. #include <fcntl.h>  
  12.   
  13. #define bufsize 255  
  14. #define namesize 20  
  15.   
  16. int tcpSocket()  
  17. {  
  18.   int n;  
  19.   
  20.   if ( (n = socket(PF_INET,SOCK_STREAM,0))==-1)  
  21.   {  
  22.     perror("TCP Socket error");  
  23.     exit(1);  
  24.   }  
  25.   return(n);  
  26. }  
  27.   
  28.   
  29. void Setsockopt(int s)  
  30. {  
  31.   int on = 1;  
  32.   struct linger linger = { 0 };  
  33.   linger.l_onoff = 1;  
  34.   linger.l_linger = 30;  
  35.   
  36.   if ( setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof(on))==-1)  
  37.   {  
  38.     perror("Setsockopt(...,SO_REUSEADDR,...)");  
  39.     exit(1);  
  40.   }  
  41.   
  42.   if ( setsockopt(s, SOL_SOCKET, SO_LINGER, (const char *) &linger, sizeof(linger))==-1)  
  43.   {  
  44.     perror("Setsockopt(...,SO_LINGER,...)");  
  45.     exit(1);  
  46.   }  
  47. }  
  48.   
  49. int Bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)  
  50. {  
  51.   return bind(sockfd,my_addr,addrlen);  
  52. }  
  53.   
  54. void Listen(int s)  
  55. {  
  56.   if (-1 == listen(s,5))  
  57.   {  
  58.     perror("Listen()");  
  59.     exit(1);  
  60.   }  
  61. }  
  62.   
  63. int Accept(int s, struct sockaddr *addr, socklen_t *addrlen)  
  64. {  
  65.   int newSocket;  
  66.   if ((newSocket=accept(s, addr, addrlen))==-1)  
  67.   {  
  68.     perror("Accept()");  
  69.     exit(1);  
  70.   }  
  71.   return newSocket;  
  72. }  
  73.   
  74.   
  75.   
  76.   
  77. void Connect(int  sockfd,  const  struct sockaddr *sock_addr)  
  78. {  
  79.   if (-1 == connect(sockfd, sock_addr, sizeof(*sock_addr)))  
  80.   {  
  81.     printf("Server haven't started\n");  
  82.     exit(1);  
  83.   }  
  84. }  
  85.   
  86. void GetHostName(char *buffer, int length)  
  87. {  
  88.   struct utsname sysname = { 0 };  
  89.   int status = 0;  
  90.   
  91.   status = uname(&sysname);  
  92.   if (-1 != status)  
  93.   {  
  94.     strncpy(buffer, sysname.nodename, length);  
  95.   }  
  96.   else  
  97.   {  
  98.     perror("GetHostName()");  
  99.     exit(1);  
  100.   }  
  101. }  
  102.   
  103. void CreateSockAddr(const char *hostname,struct sockaddr_in *sockaddress,int port)  
  104. {  
  105.   struct hostent *host = NULL;  
  106.   host = gethostbyname(hostname);  
  107.   if (NULL == host)  
  108.   {  
  109.     host = gethostbyaddr(hostname,  
  110.                          strlen(hostname), AF_INET);  
  111.     if (NULL == host)  
  112.     {  
  113.       perror("Error resolving server address");  
  114.       exit(1);  
  115.     }  
  116.   }  
  117.   (void) memset(sockaddress, 0, sizeof(sockaddress));  
  118.   (void) memcpy(&((*sockaddress).sin_addr), host->h_addr, host->h_length);  
  119.   sockaddress->sin_addr.s_addr=htonl(INADDR_ANY);  
  120.   sockaddress->sin_family = AF_INET;  
  121.   sockaddress->sin_port = htons(port);  
  122. }  
  123.   
  124. ssize_t Send(int s, const void *buf)  
  125. {  
  126.   ssize_t sendn;  
  127.   if( -1==(sendn=send(s, buf, strlen(buf), 0)))  
  128.   {  
  129.     perror("Send()");  
  130.     close(s);  
  131.   }  
  132.   return sendn;  
  133. }  
  134.   
  135.   
  136. ssize_t Recv(int s, void *buf)  
  137. {  
  138.   ssize_t recvn;  
  139.   
  140.   if( -1==(recvn= recv(s, buf, bufsize, 0)))  
  141.   {  
  142.     perror("Recv()");  
  143.     close(s);  
  144.   }  
  145.   return recvn;  
  146. }  
  147.   
  148.   
  149.   
  150. char *Fgets(char *s)  
  151. {  
  152.   bzero(s,bufsize);  
  153.   if(fgets(s,bufsize,stdin)==NULL)  
  154.   {  
  155.     perror("Fgets()");  
  156.     exit(1);  
  157.   }  
  158.   return s;  
  159. }  
  160.   
  161. void Rtrim(char *buf)  
  162. {  
  163.   int i;  
  164.   for(i=0;i<255;i++)  
  165.   {  
  166.     if(buf[i]=='\n')  
  167.     {  
  168.       buf[i]=0;  
  169.       break;  
  170.     }  
  171.   }  
  172. }  

server.c

 

  1. #ifdef HAVE_CONFIG_H  
  2. #include <config.h>  
  3. #endif  
  4.   
  5. #include <pthread.h>  
  6. #include "server.h"  
  7. #include "link.h"  
  8.   
  9. typedef struct threadargs  
  10. {  
  11.   int sock;  
  12.   LList *list;  
  13. }  
  14. threadargs;  
  15.   
  16. int getuser(char *buf,char *username,LList *userlist);  
  17. char iscmd(const char * message);  
  18. int useratlist(LList *userlist,char *username);  
  19. int findclientsock(LList *userlist,char *username);  
  20. char *getsecond(char *message);  
  21. char *getthird(char *message);  
  22. void domessage(char *dest,char * userfrom,char *message);  
  23. void accept_cli(threadargs *newargs);  
  24.   
  25. int main(int argc, char *argv[])  
  26. {  
  27.   int sctcp;  
  28.   char hostname[80] = "";  
  29.   struct sockaddr_in SC_link = { 0 };  
  30.   int server_port=8000;  
  31.   int childPid=0;  
  32.   static LList userlist;  
  33.   InitList(&userlist);  
  34.   pthread_t id;  
  35.   int ret;  
  36.   
  37.   printf("Server is starting\n");  
  38.   sctcp=tcpSocket();    //client-server comunicate with tcp  
  39.   Setsockopt(sctcp);        //set SO_REUSEADDR,SO_LINGER opt  
  40.   GetHostName(hostname, sizeof(hostname));  
  41.   CreateSockAddr(hostname,&SC_link,server_port);  
  42.   Bind(sctcp, (struct sockaddr *) &SC_link,sizeof(SC_link));  
  43.   Listen(sctcp);  
  44.   printf("Server started successfully and it is ready now\n");  
  45.   printf("Now entered listening mode\n");  
  46.   for (;;)  
  47.   {  
  48.     struct sockaddr_in client_sockaddr = { 0 };  
  49.     int cli_socket, cli_sock2,clientLength = sizeof(client_sockaddr);  
  50.     (void) memset(&client_sockaddr, 0, sizeof(client_sockaddr));  
  51.     cli_socket = Accept(sctcp,(struct sockaddr *) &client_sockaddr, &clientLength);  
  52.     if (-1 == cli_socket)  
  53.     {  
  54.       perror("accept()");  
  55.     }  
  56.     threadargs newargs;  
  57.     newargs.sock=cli_socket;  
  58.     newargs.list=&userlist;  
  59.     //      accept_cli(&newargs);  
  60.     ret=pthread_create(&id,NULL,(void *)accept_cli,&newargs);  
  61.     if(ret!=0)  
  62.       perror("thread create error");  
  63.   }  
  64.   
  65.   
  66.   return EXIT_SUCCESS;  
  67. }  
  68.   
  69. void accept_cli(threadargs *newargs)  
  70. {  
  71.   LList *userlist=newargs->list;  
  72.   int cli_socket=newargs->sock;  
  73.   int cli_sock2;  
  74.   int recvn;    //num of recv bytes  
  75.   char buf[bufsize+1]="";  
  76.   char buf2[bufsize+1]="";  
  77.   char cmd;  
  78.   client newcli;  
  79.   client lastuser;  //the user which client talk to last time  
  80.   bzero(&newcli,sizeof(client));  
  81.   bzero(&lastuser,sizeof(client));  
  82.   if(-1==Recv(cli_socket,buf))  
  83.     pthread_exit(NULL);  
  84.   printf("%s",buf);  
  85.   if(-1==Send(cli_socket,"Server OCP v0.0.1\n"))  
  86.     pthread_exit(NULL);  
  87.   bzero(buf,bufsize);  
  88.   if(-1==Recv(cli_socket,buf))  
  89.     pthread_exit(NULL);  
  90.   Rtrim(buf);  
  91.   while(useratlist(userlist,buf)==0) //username has been used  
  92.   {  
  93.     if(-1==Send(cli_socket,":x"))  
  94.       pthread_exit(NULL);  
  95.     bzero(buf,bufsize);  
  96.     if(-1==Recv(cli_socket,buf))  
  97.       pthread_exit(NULL);  
  98.   
  99.     Rtrim(buf);  
  100.   }  
  101.   Send (cli_socket,"Longin Successfully\n");  
  102.   
  103.   strncpy(newcli.nick,buf,strlen(buf));  
  104.   newcli.sock=cli_socket;  
  105.   ListInsert(userlist,newcli);  
  106.   
  107.   
  108.   while(1)  
  109.   {  
  110.     LNode *node=userlist->head->next; //use in :a  
  111.     bzero(buf,bufsize);  
  112.     if(Recv(cli_socket,buf)==-1)    //client offline  
  113.     {  
  114.       ListDelete(userlist,cli_socket);  
  115.       pthread_exit(NULL);  
  116.     }  
  117.     if((cmd=iscmd(buf))==0) //if message body contains only message(not have a command)  
  118.     {  
  119.       if(useratlist(userlist,lastuser.nick)==0)  
  120.   
  121.       {  
  122.         cli_sock2=lastuser.sock;  
  123.         domessage(buf2,newcli.nick,buf);  
  124.         if(-1==Send(cli_sock2,buf2))  
  125.           pthread_exit(NULL);  
  126.       }  
  127.   
  128.       else  
  129.       {  
  130.         if(-1==Send(cli_socket,"The user you want to talk isn't online\n"))  
  131.           pthread_exit(NULL);  
  132.       }  
  133.       continue;  
  134.     }  
  135.     switch(cmd)  
  136.     {  
  137.     case 'l':  
  138.       bzero(buf,bufsize);  
  139.       LNode *user=userlist->head->next;  
  140.       while(user!=NULL)  
  141.       {  
  142.         strcat(buf,user->e.nick);  
  143.         strcat(buf,"\n");  
  144.         user=user->next;  
  145.       }  
  146.   
  147.       if(-1==Send(cli_socket,buf))  
  148.         pthread_exit(NULL);  
  149.       break;  
  150.     case 'u':   //client change user which will talk to  
  151.       if(getuser(buf,lastuser.nick,userlist)!=-1)   //buf client's message //buf2 username  
  152.       {cli_sock2=findclientsock(userlist,lastuser.nick);  
  153.         lastuser.sock=cli_sock2;  
  154.         if(getthird(buf)!=NULL)  
  155.         {  
  156.           domessage(buf2,newcli.nick,getthird(buf));  
  157.           if(-1==Send(cli_sock2,buf2))  
  158.             pthread_exit(NULL);  
  159.         }  
  160.       }  
  161.       else  
  162.       {  
  163.         if(-1==Send(cli_socket,"You doesn't specify a user,or the user you want to talk to isn't online\n"))  
  164.           pthread_exit(NULL);  
  165.       }  
  166.       break;  
  167.     case 'q':   //client quit  
  168.       if(-1==Send(cli_socket,buf))  
  169.         pthread_exit(NULL);  
  170.       ListDelete(userlist,cli_socket);  
  171.       close(cli_socket);  
  172.       pthread_exit(NULL);  
  173.       break;  
  174.     case 'a':   //client talk to all user  
  175.   
  176.       while(node!=NULL)  
  177.       {  
  178.         client user=node->e;  
  179.   
  180.         cli_sock2=user.sock;  
  181.         if (cli_sock2!=cli_socket)  //don't send the message to your  
  182.           {   if(getsecond(buf)!=NULL)  //if the message body only contains the :a string  
  183.   
  184.             domessage(buf2,newcli.nick,getsecond(buf));  
  185.           if(-1==Send(cli_sock2,buf2))  
  186.             pthread_exit(NULL);  
  187.         }  
  188.   
  189.         node=node->next;  
  190.       }  
  191.       break;  
  192.     default :  
  193.       if(-1==Send(cli_socket,"Sever can't recognize your command\n"))  
  194.         pthread_exit(NULL);  
  195.   
  196.     }  
  197.   }  
  198.   
  199. }  
  200.   
  201. int getuser(char *buf,char *username,LList *userlist)   //if the user is online(int the userlist),set the username string,return 0,else return -1  
  202. {  
  203.   const char delimiters[] = " ";  
  204.   char *token, *cp;  
  205.   cp = strdup(buf);  
  206.   token = strtok (cp, delimiters);  
  207.   token = strtok (NULL, delimiters);    //token=username  
  208.   if(token==NULL) return -1;  
  209.   strncpy(username,token,namesize);  
  210.   if(username[strlen(username)-1]='\n')  
  211.     username[strlen(username)-1]=0;  
  212.   return useratlist(userlist,username);  
  213.   
  214. }  
  215.   
  216. char iscmd(const char * message)    //get command  
  217. {  
  218.   char cmd;  
  219.   if((cmd=message[0])!=':')  
  220.     return 0;  
  221.   return message[1];  
  222. }  
  223.   
  224. int useratlist(LList *userlist,char *username)  
  225. {  
  226.   LNode *node=userlist->head->next;  
  227.   client user;  
  228.   while(node!=NULL)  
  229.   {  
  230.     user=node->e;  
  231.     if(strncmp(user.nick,username,strlen(username))==0)  
  232.       return 0;  
  233.     else node=node->next;  
  234.   }  
  235.   return -1;  
  236.   
  237. }  
  238.   
  239. int findclientsock(LList *userlist,char *username)  
  240. {  
  241.   LNode *node=userlist->head->next;  
  242.   client user;  
  243.   while(node!=NULL)  
  244.   {  
  245.     user=node->e;  
  246.     if(strncmp(user.nick,username,strlen(username))==0)  
  247.       return user.sock;  
  248.     else node=node->next;  
  249.   }  
  250.   return -1;  
  251. }  
  252.   
  253. char *getsecond(char *message)  
  254. {  
  255.   const char delimiters[] = " ";  
  256.   char *token, *cp;  
  257.   cp = strdup(message);  
  258.   token = strtok (cp, delimiters);  
  259.   token = strtok (NULL, delimiters);  
  260.   return token;  
  261. }  
  262.   
  263. char *getthird(char *message)  
  264. {  
  265.   const char delimiters[] = " ";  
  266.   char *token, *cp;  
  267.   cp = strdup(message);  
  268.   token = strtok (cp, delimiters);  
  269.   token = strtok (NULL, delimiters);  
  270.   token = strtok (NULL, delimiters);  
  271.   return token;  
  272. }  
  273.   
  274.   
  275.   
  276. void domessage(char *dest,char * userfrom,char *message)  
  277. {  
  278.   strcpy(dest,"From ");  
  279.   strcat(dest,userfrom);  
  280.   strcat(dest,": ");  
  281.   strcat(dest,message);  
  282. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值