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

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);
}


 

 

你可能感兴趣的:(struct,socket,服务器,null,聊天,token)