채팅 프로그램 원본 (서버 쪽)

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
"); 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]=='
') { 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
"); 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
"); printf("Now entered listening mode
"); 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
")) 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
"); 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
")) 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,"
"); 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
")) 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
")) 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]='
') 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); }

 

좋은 웹페이지 즐겨찾기