채팅 프로그램 원본 (서버 쪽)
#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);
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Ruby의 구조체 클래스은 접근자 메서드가 있는 속성 모음입니다. 클래스를 명시적으로 작성할 필요 없이. Struct 클래스는 구성원 및 해당 값 집합을 포함하는 새 하위 클래스를 생성합니다. 각 멤버에 대해 #attr_accessor 와...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.