客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#define MAXN 1024
#define client_port 12580
struct sockaddr_in client_addr;
int client_sockfd;
static void *thread_send(void *arg)
{
char str[MAXN];
int st = *(int *) arg;
while (1)
{
memset(str, 0, sizeof(str));
read(STDIN_FILENO, str, sizeof(str));
if (send(st, str, strlen(str), 0) == -1)
{
break;
}
}
pthread_exit(NULL);
return NULL;
}
static void* thread_recv(void *arg)
{
char str[MAXN];
int st = *(int *) arg;
while (1)
{
memset(str, 0, sizeof(str));
int rv = recv(st, str, sizeof(str), 0);
if (rv <= 0)
{
if(rv == 0)
{
printf("server have already full !\n");
exit(EXIT_FAILURE);
}
break;
}
printf("%s",str);
}
pthread_exit(NULL);
return NULL;
}
void init(int argc,char * argv[])
{
char ip_addr[MAXN];
pthread_t tid1,tid2;
if(argc==1)
{
printf("Please input server ip addrsss.\n");
exit(EXIT_FAILURE);
}
else
{
if(argc>2)
{
printf("Too many parameters.\n");
exit(EXIT_FAILURE);
}
else
{
strcpy(ip_addr,argv[1]);
}
}
int client_sockfd;
memset(&client_addr,0,sizeof(client_addr));
client_addr.sin_family=AF_INET;
client_addr.sin_addr.s_addr=inet_addr(ip_addr);
client_addr.sin_port=htons(client_port);
if((client_sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("client socket creation failed");
exit(EXIT_FAILURE);
}
if(connect(client_sockfd,(struct sockaddr *)&client_addr,sizeof(struct sockaddr))<0)
{
perror("connection failed");
exit(EXIT_FAILURE);
}
printf("connected to server\n");
if(pthread_create(&tid1,NULL,thread_send,&client_sockfd)!=0)
{
exit(EXIT_FAILURE);
}
if(pthread_create(&tid2,NULL,thread_recv,&client_sockfd)!=0)
{
exit(EXIT_FAILURE);
}
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
close(client_sockfd);
}
int main(int argc,char * argv[])
{
init(argc,argv);
return 0;
}
服务器端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#define MAXN 1024
#define backlog 5
#define server_port 12580
struct client
{
int id;
int client_sockfd;
int vis;
pthread_t tid;
char name[MAXN];
}client_data[MAXN];
int sz;
int thread_num;
pthread_mutex_t mutex;
int server_sockfd;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
void del_client(int id)
{
int tmp_id=id;
pthread_mutex_lock(&mutex);
int i;
char buf[MAXN];
int client_sockfd;
strcpy(buf,"one client logout:");
strcat(buf,client_data[tmp_id].name);
strcat(buf,"\n");
for(i=0;i<MAXN;i++)
{
if(client_data[i].vis)
{
if(i!=tmp_id)
{
client_sockfd=client_data[i].client_sockfd;
send(client_sockfd,buf,strlen(buf),0);
}
else
{
client_data[i].client_sockfd=-1;
client_data[i].name[0]='\0';
client_data[i].vis=0;
client_data[i].tid=0;
sz--;
thread_num--;
printf("The current number of the clients online is:%d\n",sz);
}
}
}
pthread_mutex_unlock(&mutex);
}
void add_client(int id,char *ip)
{
int tmp_id=id;
pthread_mutex_lock(&mutex);
int i;
int client_sockfd;
char buf[MAXN];
strcpy(client_data[tmp_id].name,ip);
for(i=0;i<MAXN;i++)
{
if(client_data[i].vis)
{
client_sockfd=client_data[i].client_sockfd;
strcpy(buf,"new user:");
strcat(buf,ip);
strcat(buf,"\n");
send(client_sockfd,buf,strlen(buf),0);
}
}
client_data[tmp_id].vis=1;
sz++;
printf("The current number of the clients online is:%d\n",sz);
pthread_mutex_unlock(&mutex);
}
void send_all(int id,char *buf)
{
int i;
int client_sockfd;
char tmp[MAXN];
strcpy(tmp,client_data[id].name);
strcat(tmp,":");
strcat(tmp,buf);
strcat(buf,"\n");
for(i=0;i<MAXN;i++)
{
if(i!=id && client_data[i].vis)
{
client_sockfd=client_data[i].client_sockfd;
send(client_sockfd,tmp,strlen(tmp),0);
}
}
}
void * process_message(void *id)
{
if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL))
{
perror("Thread pthread_setcancelstate failed");
exit(EXIT_FAILURE);
}
if(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL))
{
perror("Thread pthread_setcanceltype failed");
exit(EXIT_FAILURE);
}
int tmp_id=(int)id;
int client_sockfd=client_data[tmp_id].client_sockfd;
char buf[MAXN];
char str[MAXN];
while(1)
{
memset(buf, 0, sizeof(buf));
int rv = recv(client_sockfd, buf, sizeof(buf), 0);
strcpy(str,client_data[tmp_id].name);
strcat(str,":");
strcat(str,buf);
if(rv>0)
{
printf("%s", str);
send_all(tmp_id,buf);
}
else
{
del_client(tmp_id);
break;
}
}
pthread_exit(NULL);
close(client_sockfd);
}
void create_client_thread(int client_sockfd,char *ip)
{
pthread_attr_t thread_attr;
if(pthread_attr_init(&thread_attr))
{
perror("Attribute creation failed");
exit(EXIT_FAILURE);
}
if(pthread_attr_setdetachstate(&thread_attr,PTHREAD_CREATE_DETACHED))
{
perror("Setting detach attribute failed");
exit(EXIT_FAILURE);
}
int i;
for(i=0;i<MAXN;i++)
{
if(client_data[i].tid==0 && client_data[i].client_sockfd==-1)
{
client_data[i].client_sockfd=client_sockfd;
if(pthread_create(&client_data[i].tid,&thread_attr,process_message,(void *)i))
{
perror("client thread creation failed");
exit(EXIT_FAILURE);
}
add_client(i,ip);
thread_num++;
break;
}
}
}
void init()
{
int i;
char str[MAXN];
sz=0;
thread_num=0;
for(i=0;i<MAXN;i++)
{
client_data[i].id=i;
client_data[i].vis=0;
client_data[i].tid=0;
client_data[i].client_sockfd=-1;
client_data[i].name[0]='\0';
}
if(pthread_mutex_init(&mutex,NULL))
{
perror("initialize client_mutex failed");
exit(EXIT_FAILURE);
}
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=INADDR_ANY;
server_addr.sin_port=htons(server_port);
if((server_sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("server socket creation failed");
exit(EXIT_FAILURE);
}
if(bind(server_sockfd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr))<0)
{
perror("socket bind failed");
exit(EXIT_FAILURE);
}
listen(server_sockfd,backlog);
int client_sockfd;
int sin_size;
sin_size=sizeof(struct sockaddr_in);
while(1)
{
if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&client_addr,(socklen_t*)&sin_size))<0)
{
perror("accept client socket failed");
exit(EXIT_FAILURE);
}
strcpy(str,inet_ntoa(client_addr.sin_addr));
printf("accept client %s\n",str);
create_client_thread(client_sockfd,str);
}
close(server_sockfd);
}
int main(int argc,char *argv[])
{
init();
exit(EXIT_SUCCESS);
}
Makefile
LIBS = -lpthread
OBJS1 = client.o
OBJS2 = server.o
main: ${OBJS1} ${OBJS2}
cc -o client ${OBJS1} ${LIBS}
cc -o server ${OBJS2} ${LIBS}
clean:
rm -f main ${OBJS1} ${OBJS2}