转载自:http://blog.csdn.net/mafuli007/article/details/7232864
server.h //定义一些函数
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/utsname.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <unistd.h>
- #include <fcntl.h>
- #define bufsize 255
- #define namesize 20
- int tcpSocket()
- {
- int n;
- if ( (n = socket(PF_INET,SOCK_STREAM,0))==-1)
- {
- perror("TCP Socket error");
- exit(1);
- }
- return(n);
- }
- void Setsockopt(int s)
- {
- int on = 1;
- struct linger linger = { 0 };
- linger.l_onoff = 1;
- linger.l_linger = 30;
- if ( setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof(on))==-1)
- {
- perror("Setsockopt(...,SO_REUSEADDR,...)");
- exit(1);
- }
- if ( setsockopt(s, SOL_SOCKET, SO_LINGER, (const char *) &linger, sizeof(linger))==-1)
- {
- perror("Setsockopt(...,SO_LINGER,...)");
- exit(1);
- }
- }
- int Bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
- {
- return bind(sockfd,my_addr,addrlen);
- }
- void Listen(int s)
- {
- if (-1 == listen(s,5))
- {
- perror("Listen()");
- exit(1);
- }
- }
- int Accept(int s, struct sockaddr *addr, socklen_t *addrlen)
- {
- int newSocket;
- if ((newSocket=accept(s, addr, addrlen))==-1)
- {
- perror("Accept()");
- exit(1);
- }
- return newSocket;
- }
- void Connect(int sockfd, const struct sockaddr *sock_addr)
- {
- if (-1 == connect(sockfd, sock_addr, sizeof(*sock_addr)))
- {
- printf("Server haven't started\n");
- exit(1);
- }
- }
- void GetHostName(char *buffer, int length)
- {
- struct utsname sysname = { 0 };
- int status = 0;
- status = uname(&sysname);
- if (-1 != status)
- {
- strncpy(buffer, sysname.nodename, length);
- }
- else
- {
- perror("GetHostName()");
- exit(1);
- }
- }
- void CreateSockAddr(const char *hostname,struct sockaddr_in *sockaddress,int port)
- {
- struct hostent *host = NULL;
- host = gethostbyname(hostname);
- if (NULL == host)
- {
- host = gethostbyaddr(hostname,
- strlen(hostname), AF_INET);
- if (NULL == host)
- {
- perror("Error resolving server address");
- exit(1);
- }
- }
- (void) memset(sockaddress, 0, sizeof(sockaddress));
- (void) memcpy(&((*sockaddress).sin_addr), host->h_addr, host->h_length);
- sockaddress->sin_addr.s_addr=htonl(INADDR_ANY);
- sockaddress->sin_family = AF_INET;
- sockaddress->sin_port = htons(port);
- }
- ssize_t Send(int s, const void *buf)
- {
- ssize_t sendn;
- if( -1==(sendn=send(s, buf, strlen(buf), 0)))
- {
- perror("Send()");
- close(s);
- }
- return sendn;
- }
- ssize_t Recv(int s, void *buf)
- {
- ssize_t recvn;
- if( -1==(recvn= recv(s, buf, bufsize, 0)))
- {
- perror("Recv()");
- close(s);
- }
- return recvn;
- }
- char *Fgets(char *s)
- {
- bzero(s,bufsize);
- if(fgets(s,bufsize,stdin)==NULL)
- {
- perror("Fgets()");
- exit(1);
- }
- return s;
- }
- void Rtrim(char *buf)
- {
- int i;
- for(i=0;i<255;i++)
- {
- if(buf[i]=='\n')
- {
- buf[i]=0;
- break;
- }
- }
- }
server.c
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <pthread.h>
- #include "server.h"
- #include "link.h"
- typedef struct threadargs
- {
- int sock;
- LList *list;
- }
- threadargs;
- int getuser(char *buf,char *username,LList *userlist);
- char iscmd(const char * message);
- int useratlist(LList *userlist,char *username);
- int findclientsock(LList *userlist,char *username);
- char *getsecond(char *message);
- char *getthird(char *message);
- void domessage(char *dest,char * userfrom,char *message);
- void accept_cli(threadargs *newargs);
- int main(int argc, char *argv[])
- {
- int sctcp;
- char hostname[80] = "";
- struct sockaddr_in SC_link = { 0 };
- int server_port=8000;
- int childPid=0;
- static LList userlist;
- InitList(&userlist);
- pthread_t id;
- int ret;
- printf("Server is starting\n");
- sctcp=tcpSocket(); //client-server comunicate with tcp
- Setsockopt(sctcp); //set SO_REUSEADDR,SO_LINGER opt
- GetHostName(hostname, sizeof(hostname));
- CreateSockAddr(hostname,&SC_link,server_port);
- Bind(sctcp, (struct sockaddr *) &SC_link,sizeof(SC_link));
- Listen(sctcp);
- printf("Server started successfully and it is ready now\n");
- printf("Now entered listening mode\n");
- for (;;)
- {
- struct sockaddr_in client_sockaddr = { 0 };
- int cli_socket, cli_sock2,clientLength = sizeof(client_sockaddr);
- (void) memset(&client_sockaddr, 0, sizeof(client_sockaddr));
- cli_socket = Accept(sctcp,(struct sockaddr *) &client_sockaddr, &clientLength);
- if (-1 == cli_socket)
- {
- perror("accept()");
- }
- threadargs newargs;
- newargs.sock=cli_socket;
- newargs.list=&userlist;
- // accept_cli(&newargs);
- ret=pthread_create(&id,NULL,(void *)accept_cli,&newargs);
- if(ret!=0)
- perror("thread create error");
- }
- return EXIT_SUCCESS;
- }
- void accept_cli(threadargs *newargs)
- {
- LList *userlist=newargs->list;
- int cli_socket=newargs->sock;
- int cli_sock2;
- int recvn; //num of recv bytes
- char buf[bufsize+1]="";
- char buf2[bufsize+1]="";
- char cmd;
- client newcli;
- client lastuser; //the user which client talk to last time
- bzero(&newcli,sizeof(client));
- bzero(&lastuser,sizeof(client));
- if(-1==Recv(cli_socket,buf))
- pthread_exit(NULL);
- printf("%s",buf);
- if(-1==Send(cli_socket,"Server OCP v0.0.1\n"))
- pthread_exit(NULL);
- bzero(buf,bufsize);
- if(-1==Recv(cli_socket,buf))
- pthread_exit(NULL);
- Rtrim(buf);
- while(useratlist(userlist,buf)==0) //username has been used
- {
- if(-1==Send(cli_socket,":x"))
- pthread_exit(NULL);
- bzero(buf,bufsize);
- if(-1==Recv(cli_socket,buf))
- pthread_exit(NULL);
- Rtrim(buf);
- }
- Send (cli_socket,"Longin Successfully\n");
- strncpy(newcli.nick,buf,strlen(buf));
- newcli.sock=cli_socket;
- ListInsert(userlist,newcli);
- while(1)
- {
- LNode *node=userlist->head->next; //use in :a
- bzero(buf,bufsize);
- if(Recv(cli_socket,buf)==-1) //client offline
- {
- ListDelete(userlist,cli_socket);
- pthread_exit(NULL);
- }
- if((cmd=iscmd(buf))==0) //if message body contains only message(not have a command)
- {
- if(useratlist(userlist,lastuser.nick)==0)
- {
- cli_sock2=lastuser.sock;
- domessage(buf2,newcli.nick,buf);
- if(-1==Send(cli_sock2,buf2))
- pthread_exit(NULL);
- }
- else
- {
- if(-1==Send(cli_socket,"The user you want to talk isn't online\n"))
- pthread_exit(NULL);
- }
- continue;
- }
- switch(cmd)
- {
- case 'l':
- bzero(buf,bufsize);
- LNode *user=userlist->head->next;
- while(user!=NULL)
- {
- strcat(buf,user->e.nick);
- strcat(buf,"\n");
- user=user->next;
- }
- if(-1==Send(cli_socket,buf))
- pthread_exit(NULL);
- break;
- case 'u': //client change user which will talk to
- if(getuser(buf,lastuser.nick,userlist)!=-1) //buf client's message //buf2 username
- {cli_sock2=findclientsock(userlist,lastuser.nick);
- lastuser.sock=cli_sock2;
- if(getthird(buf)!=NULL)
- {
- domessage(buf2,newcli.nick,getthird(buf));
- if(-1==Send(cli_sock2,buf2))
- pthread_exit(NULL);
- }
- }
- else
- {
- if(-1==Send(cli_socket,"You doesn't specify a user,or the user you want to talk to isn't online\n"))
- pthread_exit(NULL);
- }
- break;
- case 'q': //client quit
- if(-1==Send(cli_socket,buf))
- pthread_exit(NULL);
- ListDelete(userlist,cli_socket);
- close(cli_socket);
- pthread_exit(NULL);
- break;
- case 'a': //client talk to all user
- while(node!=NULL)
- {
- client user=node->e;
- cli_sock2=user.sock;
- if (cli_sock2!=cli_socket) //don't send the message to your
- { if(getsecond(buf)!=NULL) //if the message body only contains the :a string
- domessage(buf2,newcli.nick,getsecond(buf));
- if(-1==Send(cli_sock2,buf2))
- pthread_exit(NULL);
- }
- node=node->next;
- }
- break;
- default :
- if(-1==Send(cli_socket,"Sever can't recognize your command\n"))
- pthread_exit(NULL);
- }
- }
- }
- 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
- {
- const char delimiters[] = " ";
- char *token, *cp;
- cp = strdup(buf);
- token = strtok (cp, delimiters);
- token = strtok (NULL, delimiters); //token=username
- if(token==NULL) return -1;
- strncpy(username,token,namesize);
- if(username[strlen(username)-1]='\n')
- username[strlen(username)-1]=0;
- return useratlist(userlist,username);
- }
- char iscmd(const char * message) //get command
- {
- char cmd;
- if((cmd=message[0])!=':')
- return 0;
- return message[1];
- }
- int useratlist(LList *userlist,char *username)
- {
- LNode *node=userlist->head->next;
- client user;
- while(node!=NULL)
- {
- user=node->e;
- if(strncmp(user.nick,username,strlen(username))==0)
- return 0;
- else node=node->next;
- }
- return -1;
- }
- int findclientsock(LList *userlist,char *username)
- {
- LNode *node=userlist->head->next;
- client user;
- while(node!=NULL)
- {
- user=node->e;
- if(strncmp(user.nick,username,strlen(username))==0)
- return user.sock;
- else node=node->next;
- }
- return -1;
- }
- char *getsecond(char *message)
- {
- const char delimiters[] = " ";
- char *token, *cp;
- cp = strdup(message);
- token = strtok (cp, delimiters);
- token = strtok (NULL, delimiters);
- return token;
- }
- char *getthird(char *message)
- {
- const char delimiters[] = " ";
- char *token, *cp;
- cp = strdup(message);
- token = strtok (cp, delimiters);
- token = strtok (NULL, delimiters);
- token = strtok (NULL, delimiters);
- return token;
- }
- void domessage(char *dest,char * userfrom,char *message)
- {
- strcpy(dest,"From ");
- strcat(dest,userfrom);
- strcat(dest,": ");
- strcat(dest,message);
- }