版权声明: https://blog.csdn.net/qq_39603089/article/details/85080802
使用C/S 模式,参考下图:
原代码可从直接下载,与所示代码稍有不同,有所改进与完善。
https://blog.csdn.net/qq_39603089/article/details/85327599
服务端无用户界面;
客户端情看: https://blog.csdn.net/qq_39603089/article/details/85080521
/*-------------------------服务器端chat_server.c-------------------------------
time:2018/12/18
author:zyb-dy
*/
#include
#include
#include
#include
#include //数据类型定义
#include //文件属性
#include //定义数据结构sockaddr_in
#include //提供socket函数和数据结构
#include
#include
#include
#include
#include
#include
#include
#include
#include //线程
#define THREAD_NUMBER 30 //最大链接数
#define MYPORT 8787
#define BUFFER_SIZE 1024
#define WELCOME "Welcome"
struct Users{ //表示用户与线程之间的关联
char name[50];
pthread_t thread;
char buf[BUFFER_SIZE];
int client_fd;
char address[20];
int login; //是否在线
}users[THREAD_NUMBER];
int sem_id;
//返回系统时间
void get_now_time(char *nt){
time_t tmpcal_ptr;
struct tm *tmp_ptr = NULL;
time(&tmpcal_ptr);
tmp_ptr = localtime(&tmpcal_ptr);
sprintf(nt,"%d:%d:%d", tmp_ptr->tm_hour, tmp_ptr->tm_min, tmp_ptr->tm_sec);
}
int init_sem(int sem_id, int init_value){
union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
};
union semun sem_union;
sem_union.val = init_value;
if(semctl(sem_id, 0, SETVAL, sem_union) == -1){
syslog(LOG_ERR, "Initialize semaphore");
perror("Initialize semaphore");
return -1;
}
return 0;
}
int del_sem(int sem_id){
union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
};
union semun sem_union;
if(semctl(sem_id, 1, IPC_RMID, sem_union)==-1){
syslog(LOG_ERR, "Delete semaphore");
perror("Delete semaphore");
return -1;
}
}
//P 操作函数
int sem_p(int sem_id){
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1;
sem_b.sem_flg = SEM_UNDO;
if(semop(sem_id, &sem_b, 1)==-1){
syslog(LOG_ERR, "P operation");
perror("P operation");
return -1;
}
return 0;
}
//V 操作函数
int sem_v(int sem_id){
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1;
sem_b.sem_flg = SEM_UNDO;
if(semop(sem_id, &sem_b, 1) == -1){
syslog(LOG_ERR, "V operation");
perror("V operation");
return -1;
}
return 0;
}
//发送给个人
void send_all(char loadsend[BUFFER_SIZE]){
int j;
for(j=0;j1){
buf[j]=s[i];
j++;
}else if(n==1){
if(s[i]==':'){
n++;
name[j]='\0';
j=0;
continue;
}
name[j]=s[i];
j++;
}else{
if(s[i]==':'){
n++;
sign[j]='\0';
j=0;
continue;
}
sign[j]=s[i];
j++;
}
}
if(strcmp(sign,"All")==0){
get_now_time(nt);
sprintf(send_buf,"%s用户< %s >群发消息->\t\t%s:\n\t%s","User:",se_name,nt,buf);
send_all(send_buf);
}else{
get_now_time(nt);
sprintf(send_buf,"%s用户< %s >------>\t\t%s:\n\t%s","User:",se_name,nt,buf);
send_only(name,send_buf);
}
}
//线程函数
void *thrd_func(void *arg)
{
long i = (long)arg;
int recvbytes;
char nt[10];
while(1){
memset(users[i].buf , 0, sizeof(users[i].buf));
if ((recvbytes = recv(users[i].client_fd, users[i].buf, BUFFER_SIZE, 0)) <= 0)//结束当前线程
{
char end[100];
memset(end, 0, 100);
get_now_time(nt);
sprintf(end,"%s%s%s\n用户:%s%s\n","Inform:",nt,"-通知:",users[i].name,"退出聊天室"); // 添加时间:
send_all(end);
users[i].login = 0;
sem_v(sem_id);
close(users[i].client_fd);
int n=0;
int j=0;
for(j;j
gcc chat_server.c -lpthread