实验室培训项目之即时通讯软件
这次的即时通信软件包括服务器端和客户端,服务器端在红帽的基础上用gcc写成,客户端利用C#完成,由于oracle数据库的配置问题,有部分功能还未能实现,现在实现的功能就只是聊天, 聊天记录, 文件传输, 文件记录, 会议室, 会议室记录,界面和qq类似,易于操作。
服务器端的架构是以多进程epoll为基础,建立共享的内存,通过在共享内存中实现hash来提高消息的转发效率,服务器的设计目标为可承受上万的用户连接,但由于条件有限,没办法在这个方面进行测试,套接字属于不同进程epoll间的用户,通过域套接字实现消息的进程间转发,这在一定程度上降低了系统的效率。有兴趣的同志可以联系。。邮箱290590436@qq.com。。。现在附上服务器主函数的代码。。。
这个代码一共用了一个来月,期间学到了很多东西,虽然现在并未完全完成,但也算是阶段性的成功了,所以虽然我也是个新手,但我还是将代码共享出来。。对做IM软件有兴趣的同志可以联系我获得全部代码和主要思想,当然也欢迎大牛们对我的代码进行指导,风格这个就不用说了。。由于是边学边写的,这个项目风格确实欠佳,光main函数就上千行,但是对于epoll的多进程使用我还是有一定的心得体会,epoll对于大并发的程序确实是一个神器。。现在附上main。c代码。。。请大家多指教
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/un.h>
#include "share_table.h"
#include "log.h"
#define MAXLINE 1024
#define OPEN_MAX 100
#define LISTENQ 20
#define SERV_PORT 5555
#define INFTIM 1000
#define HEADLENGTH 64
#define PATH "/home/wenhao/"
typedef struct task_t
{
int fd;
char head[HEADLENGTH+1];
char buffer[MAXLINE+1];
int n;
}task_t;
void init_semaphore_struct(struct sembuf* sem,int semnum,int semop,int semflag)
{
sem->sem_num=semnum;
sem->sem_op=semop;
sem->sem_flg=semflag;
}
int del_semaphore(int semid)
{
#if 1
return semctl(semid,0,IPC_RMID);
#endif
}
int setnonblocking(int sock)
{
int opts;
opts = fcntl(sock, F_GETFL); //操作文件描述符的一些参数,F_GETFL表示获取文件描述词状态旗标
if(opts<0)
{
perror("fcntl(sock,GETFL)");
return 10;
}
opts = opts|O_NONBLOCK; //设置为非阻塞模式
if(fcntl(sock,F_SETFL,opts)<0)
{
perror("fcntl(sock,SETFL,opts)");
return 11;
}
}
int CreateWorker(int nWorker)
{
if (0 < nWorker)
{
int bIsChild=0;
pid_t nPid;
while (!bIsChild)
{
if (0 < nWorker)
{
nPid = fork();
if (nPid > 0)
{
bIsChild = 0;
--nWorker;
}
else if (0 == nPid)
{
bIsChild = 1;
printf("create worker %d success!\n", getpid());
}
else
{
printf("fork error: %s\n", strerror(errno));
return -1;
}
}
else
{
int nStatus;
if (-1 == wait(&nStatus))
{
++nWorker;
}
}
}
}
return 0;
}
int main(int argc, char* argv[])
{
//*********************************************************初始化共享存储结构
int sem_id,semop_ret,status;
struct sembuf semwait,semsignal;
if((sem_id=semget(IPC_PRIVATE,1,PERMS))==-1)
{
fprintf(stderr,"[%d]: access semophore error\n\a",getpid(),strerror(errno));
exit(1);
}
init_semaphore_struct(&semwait,0,-1,0);
init_semaphore_struct(&semsignal,0,1,0);
if(semop(sem_id,&semsignal,1)==-1)
{
fprintf(stderr,"[%d] increment semaphore error\n\a",getpid(),strerror(errno));
if(del_semaphore(sem_id)==-1)
{
fprintf(stderr,"[%d] destroy semaphore error\n\a",getpid(),strerror(errno));
}
exit(1);
}
int shmid_online_table, shmid_hash_table, shmid_empty_list;
struct online_member *ponline;
struct online_member buf_online;
if((shmid_online_table = shmget(IPC_PRIVATE, MAX_ONLINE_NUMBER*sizeof(struct online_member), 0666 | IPC_CREAT)) == -1)
{
fprintf(stderr, "1 shmget error: %s\n", strerror(errno));
del_semaphore(sem_id);
exit(1);
}
if((shmid_hash_table = shmget(IPC_PRIVATE, BIG_PRIME*sizeof(struct hash_table), 0666 | IPC_CREAT)) == -1)
{
fprintf(stderr, "2 shmget error: %s\n", strerror(errno));
shmctl(shmid_online_table, IPC_RMID, 0);
del_semaphore(sem_id);
exit(1);
}
if((shmid_empty_list = shmget(IPC_PRIVATE, (MAX_ONLINE_NUMBER+2)*sizeof(struct empty_list), 0666 | IPC_CREAT)) == -1)
{
fprintf(stderr, "3 shmget error: %s\n", strerror(errno));
shmctl(shmid_online_table, IPC_RMID, 0);
shmctl(shmid_hash_table, IPC_RMID, 0);
del_semaphore(sem_id);
exit(1);
}
init_share_table(shmid_hash_table, shmid_empty_list, shmid_online_table);
//*********************************************************初始化共享存储结构
int i, maxi, listenfd, connfd, sockfd, epfd, nfds, msg_length, j;
ssize_t n;
char line[MAXLINE], head[HEADLENGTH+1];
socklen_t clilen = sizeof(struct sockaddr);
task_t *ptask, task, *ptask_transfer;
//声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件
struct sockaddr_in clientaddr;
struct sockaddr_in serveraddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&clientaddr, sizeof(clientaddr));
bzero(&serveraddr, sizeof(serveraddr));
// memset(&serveraddr,0x00,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
/*char *local_addr="192.168.101.22";
inet_aton(local_addr,&(serveraddr.sin_addr));*/
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port=htons(SERV_PORT);
bind(listenfd,(struct sockaddr *)&serveraddr, sizeof(serveraddr));
CreateWorker(3);
struct epoll_event ev,events[20];
//生成用于处理accept的epoll专用的文件描述符
epfd = epoll_create(256); //参数为描述符的最大范围 在此创建套接字池!!!!!!!
//生成一个epoll专用的文件描述符
//把socket设置为非阻塞方式
//setnonblocking(listenfd);
//设置与要处理的事件相关的文件描述符
ev.data.fd=listenfd;
//设置要处理的事件类型
ev.events=EPOLLIN|EPOLLET;
//ev.events=EPOLLIN;
//注册epoll事件
epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev); //在此处注册ev 针对Listenfd
//你也可以在申请其他端口的listenfd,并注册ev
//fd:关联的文件描述符
//************************************初始化unix domain socket
int unixd_sockfd = 0;
struct sockaddr_un unixd_addr;
char path[30];
char path_transfer[30];
sprintf(path, "%s%d", PATH, getpid());
printf("this pid is %d\n", getpid());
//unlink(PATH);
unixd_addr.sun_family = AF_UNIX;
//unixd_addr_transfer.sun_family = AF_UNIX;
strcpy(unixd_addr.sun_path, path);
unlink(path);
unsigned int unixd_len = strlen(unixd_addr.sun_path) + sizeof(unixd_addr.sun_family);
unixd_sockfd = socket(AF_UNIX,SOCK_DGRAM,0);
if(bind(unixd_sockfd,(struct sockaddr *)&unixd_addr,unixd_len) < 0)
{
perror("bind error");
close(unixd_sockfd);
exit(-1);
}
printf("Bind is ok\n");
bzero(path,30);
//************************************初始化unix domain socket
ev.data.fd = unixd_sockfd;
//设置要处理的事件类型
ev.events = EPOLLIN | EPOLLET;
//ev.events=EPOLLIN;
//注册epoll事件
epoll_ctl(epfd, EPOLL_CTL_ADD, unixd_sockfd, &ev);
listen(listenfd, LISTENQ);
maxi = 0;
int count;
for (count = 0; ; count++) {
//等待epoll事件的发生
nfds=epoll_wait(epfd,events,20,500);
//if(nfds > 0)
//printf("nfds: %d\n", nfds);
//处理所发生的所有事件
for(i=0;i<nfds;++i)
{
if(events[i].data.fd==listenfd)//如果新监测到一个SOCKET用户连接到了绑定的SOCKET端口,建立新的连接。
{
if((connfd = accept(listenfd,(struct sockaddr *)&clientaddr, &clilen)) < 0)
{
fprintf(stderr, "accept error : %s\n", strerror(errno));
}
printf("connfd: %d\n", connfd);
if(connfd < 0){
perror("connfd<0");
return 30;
}
ev.data.fd = connfd;
//setnonblocking(connfd);
char *str = inet_ntoa(clientaddr.sin_addr);
printf("IP %s has come,the sockfd is %d, this pid is %d: \n", str, connfd, getpid());
printf("the i = %d ,the count = %d\n",i, count);
//设置用于读操作的文件描述符
//设置用于注测的读操作事件
ev.events = EPOLLIN | EPOLLET;
//ev.events=EPOLLIN;
//注册ev
epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);
}
else if(events[i].data.fd == unixd_sockfd && (events[i].events & EPOLLIN))
{
printf("the unixdomain socket %d have data to receive, the pid: %d\n", events[i].data.fd, getpid());
bzero(head, HEADLENGTH);
if ((n = recvfrom(unixd_sockfd, head, HEADLENGTH, 0, (struct sockaddr*)&unixd_addr, &unixd_len)) < 0)
{
if (errno == ECONNRESET)
{ //连接出错,一般在客户端强制退出时出现
fprintf(stderr, "recv error : %s", strerror(errno));
close(unixd_sockfd);
events[i].data.fd = -1;
}
else
printf("读取数据时出错\n");
}
else if(n == 0)
{
printf("there's nothing");
close(unixd_sockfd);
events[i].data.fd = -1;
}
line[n] = '\0';
strncpy(buf_online.username, &head[22], 20);
semop_ret=semop(sem_id, &semwait, 1);
//
if( search_online_member(&buf_online, shmid_hash_table, shmid_empty_list, shmid_online_table) == 1)
{
semop(sem_id, &semsignal, 1);
printf("search success: %s , %d\n", buf_online.username, buf_online.fd);
ptask_transfer = NULL;
ptask_transfer = (task_t*)malloc(sizeof(task_t));
if (ptask_transfer == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask_transfer == NULL)
{
ptask_transfer = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask_transfer->buffer, MAXLINE);
/*strncpy(ptask_transfer->head, head, 2);//********用户上线指令
strncpy(&ptask_transfer->head[2], &head[2], 20);
strncpy(&ptask_transfer->head[22], buf_online.username, 20);
memcpy(&ptask_transfer->head[42], &head[42], 4);*/
memcpy(&msg_length, &head[42], 4);
memcpy(ptask_transfer->head, head, 64);
ptask_transfer->fd = buf_online.fd;
if ( msg_length != 0)
{
recvfrom(unixd_sockfd, ptask_transfer->buffer, msg_length, 0, (struct sockaddr*)&unixd_addr, &unixd_len);
printf("recv data: %s, length : %d\n", ptask_transfer->buffer, msg_length);
}
ev.data.ptr = ptask_transfer;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, buf_online.fd, &ev);
printf("epoll add finished\n");
}
}
else if(events[i].events & EPOLLIN)//如果是已经连接的用户,并且收到数据,那么进行读入。
{
//printf("the sockfd: %d have data to receive\n", events[i].data.fd);
bzero(head, HEADLENGTH);
if ( (sockfd = events[i].data.fd) < 0)
continue;
if ( (n = recv(sockfd, head, HEADLENGTH, 0)) < 0) {
if (errno == ECONNRESET) { //连接出错,一般在客户端强制退出时出现
close(sockfd);
//**********************从共享存储中删除
events[i].data.fd = -1;
}
else
printf("读取数据时出错\n");
}
else if (n == 0) {
close(sockfd);
events[i].data.fd = -1;
}
if(n < HEADLENGTH)
RecvData(sockfd, &head[n], HEADLENGTH - n);
head[n] = '\0';
//printf("n is %d\n", n);
//printf("\t the date is :%s ,size is :%d, str len is :%d\n", head, n, strlen(head));
if(strncmp(head, "LG", 2) == 0)
{
//sleep(1);
//printf("351: go into the if: head: %c%c\n", head[0], head[1]);
//*********************插入共享存储区
strncpy(buf_online.username, &head[2], 20);
strncpy(buf_online.grade, "ISRC2012", 10);
buf_online.fd = sockfd;
buf_online.pid = getpid();
buf_online.next = -1;
printf("358 buf_online.username: %s\n", buf_online.username);
semop_ret=semop(sem_id, &semwait, 1);
//
if(is_online_member(&buf_online, shmid_hash_table, shmid_empty_list, shmid_online_table) == 1)
{
printf("361 into the is online\n");
delete_online_member(&buf_online, shmid_hash_table, shmid_empty_list, shmid_online_table);
//***********************************************************************************
//挤掉冲突用户的后续操作
}
//printf("367 : before insert!!!\n");
insert_online_member(&buf_online, shmid_hash_table, shmid_empty_list, shmid_online_table);
semop(sem_id, &semsignal, 1);
//*********************插入共享存储区
printf("new client has come. username: %s,grade: %s,pid: %d\n", buf_online.username, buf_online.grade, buf_online.pid);
//设置用于写操作的文件描述符
ptask = NULL;
ptask = (task_t*)malloc(sizeof(task_t));//安全分配内存
if (ptask == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask == NULL)
{
ptask = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask, sizeof(task_t));
print_online_table(shmid_online_table, shmid_hash_table);
//*************************生成消息头和消息
msg_length = sprint_online_table(ptask->buffer, shmid_online_table, shmid_hash_table);
//printf("msg_length = %d\n", msg_length);
strncpy(ptask->head, "LG", 2);
strncpy(&ptask->head[2], "server", 20);
strncpy(&ptask->head[22], buf_online.username, 20);
//printf("348 buf_online :%s\n", buf_online.username);
memcpy(&ptask->head[42], &msg_length, 4);
//printf("381 head[42]: %s, msglen is: %d\n", &ptask->head[42], msg_length);
//*************************生成消息头和消息
//printf("head: %s\n", ptask->head);
//printf("malloc : %d\n", ptask);
ptask->fd = sockfd;
//strcpy(ptask->head, head);
//设置用于注测的写操作事件
ev.data.ptr = ptask;
ev.events = EPOLLOUT|EPOLLET;
//修改sockfd上要处理的事件为EPOLLOUT
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
//write_chatlog_s(ptask->head, ptask->bu);
bzero(head, 64);
//********************************群发上线提醒
semop_ret=semop(sem_id, &semwait, 1);
//semop(sem_id, &semsignal, 1);
for (j = 0; j < msg_length; j += 20)
{
int msg_len = 0;
strncpy(buf_online.username, &ptask->buffer[j], 20);
if(strncmp(buf_online.username, &ptask->head[22], 20) == 0)
continue;
search_online_member(&buf_online, shmid_hash_table, shmid_empty_list, shmid_online_table);
printf("search success: %s\n", buf_online.username);
if(buf_online.pid == getpid())
{
ptask_transfer = NULL;
ptask_transfer = (task_t*)malloc(sizeof(task_t));
if (ptask_transfer == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask_transfer == NULL)
{
ptask_transfer = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask_transfer, sizeof(task_t));
strncpy(ptask_transfer->head, "CA", 2);//********用户上线指令
strncpy(&ptask_transfer->head[2], &ptask->head[22], 20);
strncpy(&ptask_transfer->head[22], buf_online.username, 20);
memcpy(&ptask_transfer->head[42], &ptask->head[42], 4);
ptask_transfer->fd = buf_online.fd;
//printf("412 new events!!!");
ev.data.ptr = ptask_transfer;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, buf_online.fd, &ev);
}
else
{
sprintf(path, "%s%d", PATH, buf_online.pid);
printf("436 transfer pid: %d, this pid %d, path: %s\n", buf_online.pid, getpid(), path);
//int unixd_len = strlen(unixd_addr.sun_path)+sizeof(unixd_addr.sun_family);
int unixd_sockfd_transfer = 0;
struct sockaddr_un unixd_addr_transfer;
bzero(&unixd_addr_transfer, sizeof(unixd_addr_transfer));
strcpy(unixd_addr_transfer.sun_path, path);
unixd_addr_transfer.sun_family = AF_UNIX;
unixd_sockfd_transfer = socket(AF_UNIX,SOCK_DGRAM,0);
if(unixd_sockfd_transfer < 0)
{
perror("socket error");
exit(-1);
}
int unixd_len_transfer = strlen(unixd_addr_transfer.sun_path)+sizeof(unixd_addr_transfer.sun_family);
strncpy(head, "CA", 2);
strncpy(&head[2], &ptask->head[22], 20);
strncpy(&head[22], buf_online.username, 20);
memcpy(&head[42], &msg_len, 4);
sendto(unixd_sockfd_transfer, head, HEADLENGTH, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);
bzero(head, HEADLENGTH);
}
//printf("ready to transfer!! %j\n", j);
}
semop(sem_id, &semsignal, 1);
//printf("broadcast over!!!\n");
//*******************群发上线提醒
}
else if(strncmp(head, "LO", 2) == 0)//正常断开连接的操作
{
strncpy(buf_online.username, &head[2], 20);
strncpy(buf_online.grade, "ISRC2012", 10);
buf_online.fd = sockfd;
buf_online.pid = getpid();
buf_online.next = -1;
semop_ret=semop(sem_id, &semwait, 1);
//
delete_online_member(&buf_online, shmid_hash_table, shmid_empty_list, shmid_online_table);
semop(sem_id, &semsignal, 1);
print_online_table(shmid_online_table, shmid_hash_table);
ptask = NULL;
ptask = (task_t*)malloc(sizeof(task_t));//安全分配内存
if (ptask == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask == NULL)
{
ptask = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask, sizeof(task_t));
msg_length = sprint_online_table(ptask->buffer, shmid_online_table, shmid_hash_table);
strncpy(ptask->head, "LG", 2);
strncpy(&ptask->head[2], "server", 20);
strncpy(&ptask->head[22], buf_online.username, 20);
//printf("348 buf_online :%s\n", buf_online.username);
memcpy(&ptask->head[42], &msg_length, 4);
close(sockfd);
events[i].data.fd = -1;
//*****************群发下线提醒
semop_ret=semop(sem_id, &semwait, 1);
//
for (j = 0; j < msg_length; j += 20)
{
int msg_len = 0;
strncpy(buf_online.username, &ptask->buffer[j], 20);
if(strncmp(buf_online.username, &ptask->head[22], 20) == 0)
continue;
search_online_member(&buf_online, shmid_hash_table, shmid_empty_list, shmid_online_table);
printf("search success: %s\n", buf_online.username);
if(buf_online.pid == getpid())
{
ptask_transfer = NULL;
ptask_transfer = (task_t*)malloc(sizeof(task_t));
if (ptask_transfer == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask_transfer == NULL)
{
ptask_transfer = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask_transfer, sizeof(task_t));
strncpy(ptask_transfer->head, "CD", 2);//********用户上线指令
strncpy(&ptask_transfer->head[2], &ptask->head[22], 20);
strncpy(&ptask_transfer->head[22], buf_online.username, 20);
memcpy(&ptask_transfer->head[42], &msg_len, 4);
ptask_transfer->fd = buf_online.fd;
//printf("412 new events!!!");
ev.data.ptr = ptask_transfer;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, buf_online.fd, &ev);
}
else
{
sprintf(path, "%s%d", PATH, buf_online.pid);
//printf("436 transfer pid: %d, this pid %d, path: %s\n", buf_online.pid, getpid(), path);
//int unixd_len = strlen(unixd_addr.sun_path)+sizeof(unixd_addr.sun_family);
int unixd_sockfd_transfer = 0;
struct sockaddr_un unixd_addr_transfer;
bzero(&unixd_addr_transfer, sizeof(unixd_addr_transfer));
strcpy(unixd_addr_transfer.sun_path, path);
unixd_addr_transfer.sun_family = AF_UNIX;
unixd_sockfd_transfer = socket(AF_UNIX,SOCK_DGRAM,0);
if(unixd_sockfd_transfer < 0)
{
perror("socket error");
exit(-1);
}
int unixd_len_transfer = strlen(unixd_addr_transfer.sun_path)+sizeof(unixd_addr_transfer.sun_family);
strncpy(head, "CD", 2);
strncpy(&head[2], &ptask->head[22], 20);
strncpy(&head[22], buf_online.username, 20);
memcpy(&head[42], &ptask->head[42], 4);
sendto(unixd_sockfd_transfer, head, HEADLENGTH, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);
//free(ptask);//11-10 修改。。。。
bzero(head, HEADLENGTH);
}
//printf("ready to transfer!! %j\n", j);
}
semop(sem_id, &semsignal, 1);
//printf("broadcast over!!!\n");
//*****************群发下线提醒
//
if(ptask != NULL)
free(ptask);
ptask = NULL;
msg_length = 0;
}
else if(strncmp(head, "IM", 2) == 0)
{
strncpy(buf_online.username, &head[22], 20);
memcpy(&msg_length, &head[42], 4);
/*ptask = (task_t*)malloc(sizeof(task_t));
memcpy(ptask->head, head, 64);
recv(sockfd, ptask->buffer, msg_length, 0);*/
semop_ret=semop(sem_id, &semwait, 1);
if(search_online_member(&buf_online, shmid_hash_table, shmid_empty_list, shmid_online_table) == -1)
{
printf("can't find the user\n");
char norecvbuf[MAXLINE];
recv(sockfd, norecvbuf, msg_length, 0);
semop(sem_id, &semsignal, 1);
//离线日志的操作***************************
continue;
}
semop(sem_id, &semsignal, 1);
ev.data.fd =sockfd;
//设置用于注测的读操作事件
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
if(buf_online.pid == getpid())
{
ptask = NULL;
ptask = (task_t*)malloc(sizeof(task_t));//安全分配内存
if (ptask == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask == NULL)
{
ptask = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask, sizeof(task_t));
memcpy(ptask->head, head, 64);
if(msg_length != 0)
{
recv(sockfd, ptask->buffer, msg_length, 0);
}
//printf("563 the im data is %s\n", ptask->buffer);
write_chatlog_s(head, ptask->buffer);//写发送者聊天日志
ptask->fd = buf_online.fd;
ev.data.ptr = ptask;
ev.events = EPOLLOUT|EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, ptask->fd, &ev);
}
else
{
char im_buf[MAXLINE+1];
recv(sockfd, im_buf, msg_length, 0);
sprintf(path, "%s%d", PATH, buf_online.pid);
//printf("436 transfer pid: %d, this pid %d, path: %s\n", buf_online.pid, getpid(), path);
//int unixd_len = strlen(unixd_addr.sun_path)+sizeof(unixd_addr.sun_family);
int unixd_sockfd_transfer = 0;
struct sockaddr_un unixd_addr_transfer;
bzero(&unixd_addr_transfer,sizeof(unixd_addr_transfer));
strcpy(unixd_addr_transfer.sun_path, path);
unixd_addr_transfer.sun_family = AF_UNIX;
unixd_sockfd_transfer = socket(AF_UNIX,SOCK_DGRAM,0);
if(unixd_sockfd_transfer < 0)
{
perror("socket error");
exit(-1);
}
int unixd_len_transfer = strlen(unixd_addr_transfer.sun_path)+sizeof(unixd_addr_transfer.sun_family);
sendto(unixd_sockfd_transfer, head, HEADLENGTH, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);
sendto(unixd_sockfd_transfer, im_buf, msg_length, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);
//***********************在相应进程的域套接字接收在进行转发************
}
bzero(head, 64);
}
else if(strncmp(head, "HM", 2) == 0)
{
int num;
memcpy(&num, &head[42], 4);
ptask = NULL;
ptask = (task_t*)malloc(sizeof(task_t));//安全分配内存
if (ptask == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask == NULL)
{
ptask = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask, sizeof(task_t));
int len;
len = read_chatlog(head, ptask->buffer, num);
if(len == -1)
{
//free(ptask);
len = 0;
strncpy(ptask->head, head, 2);
strncpy(&ptask->head[2], &head[22], 20);
strncpy(&ptask->head[22], &head[2], 20);
memcpy(&ptask->head[42], &len, 4);
memcpy(&ptask->head[46], &head[46], 18);
bzero(head, 64);
ptask->fd = sockfd;
ev.data.ptr = ptask;
ev.events = EPOLLOUT | EPOLLET;
//修改sockfd上要处理的事件为EPOLLOUT
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
continue;
}
strncpy(ptask->head, head, 2);
strncpy(&ptask->head[2], &head[22], 20);
strncpy(&ptask->head[22], &head[2], 20);
memcpy(&ptask->head[42], &len, 4);
memcpy(&ptask->head[46], &head[46], 18);
printf("hm the number: %d, the len: %d\n", num, len);
ptask->fd = sockfd;
ev.data.ptr = ptask;
ev.events = EPOLLOUT | EPOLLET;
//修改sockfd上要处理的事件为EPOLLOUT
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
}
else if(strncmp(head, "FS", 2) == 0)
{
//********将最初收到的文件信息存入临时文件
char file_name[30];
bzero(file_name, 30);
recv(sockfd, &file_name[14], 16, 0);
strncpy(file_name, &head[50], 14);
char sender[20];
strncpy(sender, &head[2], 20);
char file_path[100];
sprintf(file_path, "./log/file/%s/%s.tmp", sender, file_name);
int fd = open(file_path, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
char file_info[40];
bzero(file_info, 40);
int len;
memcpy(&len, &head[42], 4);
recv(sockfd, file_info, len, 0);
if(fd == -1)
{
fprintf(stderr, "open tmp error: %s\n", strerror(errno));
continue;
}
write(fd, head, 50);
write(fd, file_name, 30);
write(fd, file_info, len);
close(fd);
//*******写日志记录
char log_path[100];
sprintf(log_path, "./log/file/%s/filelog", sender);
int log_fd = open(log_path, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
write(fd, head, 50);
write(fd, file_name, 30);
write(fd, file_info, len);
close(log_fd);
ev.data.fd =sockfd;
//设置用于注测的读操作事件
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
bzero(head, HEADLENGTH);
}
else if(strncmp(head, "FM", 2) == 0)
{
char file_name[30];
bzero(file_name, 30);
recv(sockfd, &file_name[14], 16, 0);
strncpy(file_name, &head[50], 14);
char sender[20];
strncpy(sender, &head[2], 20);
char file_path[100];
sprintf(file_path, "./log/file/%s/%s", sender, file_name);
int len, rest;
memcpy(&len, &head[42], 4);
memcpy(&rest, &head[46], 4);
int fd = open(file_path, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR );
if(fd == -1)
{
fprintf(stderr, "open tmp error: %s\n", strerror(errno));
continue;
}
char fmbuf[MAXLINE];
bzero(fmbuf, MAXLINE);
//int file_len = recv(sockfd, fmbuf, len, 0);
RecvData(sockfd, fmbuf, len);
WriteData(fd, fmbuf, len);
//printf("file_len: %d\n", file_len);
close(fd);
if(rest == 0)
{
//转发文件的到来的提醒,删除临时文件
//char receiver[20];
bzero(buf_online.username, 20);
strncpy(buf_online.username, &head[22], 20);
semop_ret=semop(sem_id, &semwait, 1);
if(search_online_member(&buf_online, shmid_hash_table, shmid_empty_list, shmid_online_table) == -1)
{
printf("can't find the user\n");
semop(sem_id, &semsignal, 1);
//**********************离线操作
}
semop(sem_id, &semsignal, 1);
char tmp_path[100];
bzero(tmp_path, 100);
sprintf(tmp_path, "./log/file/%s/%s.tmp", sender, file_name);
int tmp_fd = open(tmp_path, O_RDWR);
char buf[104];//tmp中文件信息的长度
bzero(buf, 104);
int tmp_len = 0;
while(1)
{
tmp_len += read(tmp_fd, &buf[tmp_len], 104-tmp_len);
if(tmp_len < 0 | tmp_len == 104)
{
break;
}
}
if(tmp_len < 0)
{
fprintf(stderr, "open tmp error: %s\n", strerror(errno));
continue;
}
/*printf("768 buffer %s\n", buf);
int j;
for(j = 0; j < tmp_len; j++)
printf(" %c", buf[j]);*/
if(buf_online.pid == getpid())
{
ptask = NULL;
ptask = (task_t*)malloc(sizeof(task_t));
if (ptask == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask == NULL)
{
ptask = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask, sizeof(task_t));
memcpy(ptask->head, buf, 64);
memcpy(ptask->buffer, &buf[64], 40);
tmp_len -= 64;
memcpy(&ptask->head[42], &tmp_len, 4);
ptask->fd = buf_online.fd;
ev.data.ptr = ptask;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, ptask->fd, &ev);
}
else
{
char tmp_head[HEADLENGTH];
memcpy(&tmp_head, buf, 64);
tmp_len -= 64;
memcpy(&tmp_head, &tmp_len, 4);
sprintf(path, "%s%d", PATH, buf_online.pid);
int unixd_sockfd_transfer = 0;
struct sockaddr_un unixd_addr_transfer;
bzero(&unixd_addr_transfer,sizeof(unixd_addr_transfer));
strcpy(unixd_addr_transfer.sun_path, path);
unixd_addr_transfer.sun_family = AF_UNIX;
unixd_sockfd_transfer = socket(AF_UNIX,SOCK_DGRAM,0);
if(unixd_sockfd_transfer < 0)
{
perror("socket error");
exit(-1);
}
int unixd_len_transfer = strlen(unixd_addr_transfer.sun_path)+sizeof(unixd_addr_transfer.sun_family);
sendto(unixd_sockfd_transfer, tmp_head, HEADLENGTH, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);
sendto(unixd_sockfd_transfer, &buf[64], tmp_len, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);
}
close(tmp_fd);
//*************************写接收者的日志
char receiver_file_path[100], receiver_log_path[100];
bzero(receiver_file_path, 100);
bzero(receiver_log_path, 100);
char receiver[20];
bzero(receiver, 20);
strncpy(receiver, &head[22], 20);
sprintf(receiver_file_path, "./log/file/%s/%s", receiver, file_name);
sprintf(receiver_log_path, "./log/file/%s/filelog", receiver);
if(link(file_path, receiver_file_path) == -1)
{
fprintf(stderr, "link error!!\n", strerror(errno));
}
int log_fd = open(receiver_log_path, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
if(log_fd == -1)
{
fprintf(stderr, "link error!!\n", strerror(errno));
}
else
{
int write_len = write(log_fd, buf, 104);
if (write_len < 104)
{
WriteData(log_fd, &buf[write_len], 104-write_len);
}
close(log_fd);
//write(file_name, );
}
char cmd[140];
bzero(cmd, 140);
sprintf(cmd, "rm ./log/file/%s/\"%s.tmp\"", sender, file_name);
//printf("cmd: %s\n", cmd);
system(cmd);
bzero(&buf_online, sizeof(buf_online));
}
ev.data.fd =sockfd;
//设置用于注测的读操作事件
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
bzero(head, HEADLENGTH);
}
else if(strncmp(head, "FD", 2) == 0)
{
char file_name[30];
bzero(file_name, 30);
recv(sockfd, &file_name[14], 16, 0);
memcpy(file_name, &head[50], 14);
char receiver[20];
bzero(receiver, 20);
strncpy(receiver, &head[22], 20);
int pos, len;
memcpy(&pos, &head[46], 4);
char file_path[100];
bzero(file_path, 100);
sprintf(file_path, "./log/file/%s/%s", receiver, file_name);
int fd = open(file_path, O_RDONLY);
if(fd == -1)
{
fprintf(stderr, "read file: %s error: %s\n", file_path, strerror(errno));
bzero(head, 64);
continue;
}
else
{
ptask = NULL;
ptask = (task_t*)malloc(sizeof(task_t));
if (ptask == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask == NULL)
{
ptask = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask, sizeof(task_t));
if(lseek(fd, pos, SEEK_SET) == -1)
{
fprintf(stderr,"lseek error: %s\n", strerror(errno));
}
printf("pos: %d\n", pos);
memcpy(ptask->buffer, &file_name[14], 16);
len = read(fd, &ptask->buffer[16], 1008);//为了扩展文件名,,,此处每次最多读1010字节
pos += len;
len += 16;
memcpy(&head[46], &pos, 4);
memcpy(&head[42], &len, 4);
memcpy(ptask->head, head, 64);
ptask->fd = sockfd;
ev.data.ptr = ptask;
//设置用于注测的读操作事件
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, ptask->fd, &ev);
}
close(fd);
bzero(head, 64);
}
else if(strncmp(head, "HF", 2) == 0)
{
char log_path[100], sender[20];
bzero(log_path, 100);
bzero(sender, 20);
memcpy(sender, &head[2], 20);
sprintf(log_path, "./log/file/%s/filelog", sender);
/*
int file_log = open(log_path, O_RDONLY);
if(file_log < 0)
{
fprintf(stderr, "open file log error: %s\n", strerror(errno));
continue;
}*/
ptask = NULL;
ptask = (task_t*)malloc(sizeof(task_t));//安全分配内存
if (ptask == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask == NULL)
{
ptask = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask, sizeof(task_t));
memcpy(ptask->head, head, 64);
memcpy(ptask->buffer, log_path, 100);
ptask->fd = sockfd;
ev.data.ptr = ptask;
ev.events = EPOLLOUT | EPOLLET;
//修改sockfd上要处理的事件为EPOLLOUT
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
}
else if(strncmp(head, "MC", 2) == 0)
{
char meeting_name[40];
bzero(meeting_name, 40);
RecvData(sockfd, meeting_name, 40);
int mfd = open("./log/meeting/meeting", O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
if(mfd < 0)
{
fprintf(stderr, "open meeting error: %s\n", strerror(errno));
continue;
}
WriteData(mfd, meeting_name, 40);
char meeting_member[120], meeting_log[120];
bzero(meeting_member, 120);
bzero(meeting_log, 120);
sprintf(meeting_log, "./log/meeting/meeting_log_%s", meeting_name);
sprintf(meeting_member, "./log/meeting/meeting_member_%s", meeting_name);
int lfd = open(meeting_log, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
int mbfd = open(meeting_member, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
if(lfd < 0 || mbfd < 0)
{
fprintf(stderr, "open log error: %s\n", strerror(errno));
close(mfd);
continue;
}
WriteData(mbfd, &head[2], 20);//*******************************************是否写进日志
close(mfd);
close(lfd);
close(mbfd);
ev.data.fd =sockfd;
//设置用于注测的读操作事件
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
}
else if(strncmp(head, "MI", 2) == 0 || strncmp(head, "MR", 2) == 0)
{
char meeting_name[40];
bzero(meeting_name, 40);
RecvData(sockfd, meeting_name, 40);
bzero(&buf_online, sizeof(buf_online));
//int len = 40;
strncpy(buf_online.username, &head[22], 20);
memcpy(&msg_length, &head[42], 4);
char data[MAXLINE-40];
if(msg_length - 40 > 0)
{
bzero(data, MAXLINE-40);
RecvData(sockfd, data, msg_length - 40);
}
/*ptask = (task_t*)malloc(sizeof(task_t));
memcpy(ptask->head, head, 64);
recv(sockfd, ptask->buffer, msg_length, 0);*/
semop_ret=semop(sem_id, &semwait, 1);
if(search_online_member(&buf_online, shmid_hash_table, shmid_empty_list, shmid_online_table) == -1)
{
printf("can't find the user\n");
//char norecvbuf[MAXLINE];
//recv(sockfd, norecvbuf, msg_length, 0);
semop(sem_id, &semsignal, 1);
continue;
}
semop(sem_id, &semsignal, 1);
ev.data.fd =sockfd;
//设置用于注测的读操作事件
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
if(buf_online.pid == getpid())
{
ptask = NULL;
ptask = (task_t*)malloc(sizeof(task_t));//安全分配内存
if (ptask == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask == NULL)
{
ptask = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask, sizeof(task_t));
memcpy(ptask->head, head, 64);
memcpy(ptask->buffer, meeting_name, 40);
if(msg_length > 40)
memcpy(&ptask->buffer[40], data, msg_length - 40);
/*if(msg_length != 0)
{
recv(sockfd, ptask->buffer, msg_length, 0);
}*/
//printf("563 the im data is %s\n", ptask->buffer);
//write_chatlog_s(head, ptask->buffer);//写发送者聊天日志
ptask->fd = buf_online.fd;
ev.data.ptr = ptask;
ev.events = EPOLLOUT|EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, ptask->fd, &ev);
}
else
{
//char im_buf[MAXLINE+1];
//recv(sockfd, im_buf, msg_length, 0);
sprintf(path, "%s%d", PATH, buf_online.pid);
//printf("436 transfer pid: %d, this pid %d, path: %s\n", buf_online.pid, getpid(), path);
//int unixd_len = strlen(unixd_addr.sun_path)+sizeof(unixd_addr.sun_family);
int unixd_sockfd_transfer = 0;
struct sockaddr_un unixd_addr_transfer;
bzero(&unixd_addr_transfer,sizeof(unixd_addr_transfer));
strcpy(unixd_addr_transfer.sun_path, path);
unixd_addr_transfer.sun_family = AF_UNIX;
unixd_sockfd_transfer = socket(AF_UNIX,SOCK_DGRAM,0);
if(unixd_sockfd_transfer < 0)
{
perror("socket error");
exit(-1);
}
int unixd_len_transfer = strlen(unixd_addr_transfer.sun_path)+sizeof(unixd_addr_transfer.sun_family);
sendto(unixd_sockfd_transfer, head, HEADLENGTH, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);
sendto(unixd_sockfd_transfer, meeting_name, 40, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);
if(msg_length > 40)
sendto(unixd_sockfd_transfer, data, msg_length - 40, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);
//***********************在相应进程的域套接字接收在进行转发************
}
bzero(head, 64);
}
else if(strncmp(head, "MJ", 2) == 0 || strncmp(head, "MA", 2) == 0)//MJ 需要些日志
{
char meeting_name[40];
bzero(meeting_name, 40);
RecvData(sockfd, meeting_name, 40);
bzero(&buf_online, sizeof(buf_online));
//int len = 40;
strncpy(buf_online.username, &head[22], 20);
memcpy(&msg_length, &head[42], 4);
semop_ret=semop(sem_id, &semwait, 1);
if(search_online_member(&buf_online, shmid_hash_table, shmid_empty_list, shmid_online_table) == -1)
{
printf("can't find the user\n");
//char norecvbuf[MAXLINE];
//recv(sockfd, norecvbuf, msg_length, 0);
semop(sem_id, &semsignal, 1);
continue;
}
semop(sem_id, &semsignal, 1);
if (strncmp(head, "MJ", 2) == 0)
{
char logpath[120];
bzero(logpath, 120);
sprintf(logpath, "./log/meeting/meeting_member_%s", meeting_name);
int logfd = open(logpath, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
if (logfd < 0)
{
fprintf(stderr, "open log error: %s!!\n", strerror(errno));
}
else
{
WriteData(logfd, &head[2], 20);
close(logfd);
}
}
ev.data.fd =sockfd;
//设置用于注测的读操作事件
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
if(buf_online.pid == getpid())
{
ptask = NULL;
ptask = (task_t*)malloc(sizeof(task_t));//安全分配内存
if (ptask == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask == NULL)
{
ptask = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask, sizeof(task_t));
memcpy(ptask->head, head, 64);
memcpy(ptask->buffer, meeting_name, 40);
/*if(msg_length > 40)
memcpy(&ptask->buffer[40], data, msg_length - 40);*/
/*if(msg_length != 0)
{
recv(sockfd, ptask->buffer, msg_length, 0);
}*/
//printf("563 the im data is %s\n", ptask->buffer);
//write_chatlog_s(head, ptask->buffer);//写发送者聊天日志
ptask->fd = buf_online.fd;
ev.data.ptr = ptask;
ev.events = EPOLLOUT|EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, ptask->fd, &ev);
}
else
{
//char im_buf[MAXLINE+1];
//recv(sockfd, im_buf, msg_length, 0);
sprintf(path, "%s%d", PATH, buf_online.pid);
//printf("436 transfer pid: %d, this pid %d, path: %s\n", buf_online.pid, getpid(), path);
//int unixd_len = strlen(unixd_addr.sun_path)+sizeof(unixd_addr.sun_family);
int unixd_sockfd_transfer = 0;
struct sockaddr_un unixd_addr_transfer;
bzero(&unixd_addr_transfer,sizeof(unixd_addr_transfer));
strcpy(unixd_addr_transfer.sun_path, path);
unixd_addr_transfer.sun_family = AF_UNIX;
unixd_sockfd_transfer = socket(AF_UNIX,SOCK_DGRAM,0);
if(unixd_sockfd_transfer < 0)
{
perror("socket error");
exit(-1);
}
int unixd_len_transfer = strlen(unixd_addr_transfer.sun_path)+sizeof(unixd_addr_transfer.sun_family);
sendto(unixd_sockfd_transfer, head, HEADLENGTH, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);
sendto(unixd_sockfd_transfer, meeting_name, 40, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);
/*if(msg_length > 40)
sendto(unixd_sockfd_transfer, data, msg_length - 40, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);*/
//***********************在相应进程的域套接字接收在进行转发************
}
bzero(head, 64);
}
else if(strncmp(head, "MM", 2) == 0)//写日志
{
printf("receive MM head : %s\n", head);
char meeting_name[40];
bzero(meeting_name, 40);
int len, pos, ll;
memcpy(&len, &head[42], 4);
memcpy(&pos, &head[46], 4);
printf("pos: %d, len: %d\n", pos, len);
char *members = (char *)malloc(pos*sizeof(char));
char *message = (char *)malloc(len*sizeof(char));
ll = len + 40;
memcpy(&head[42], &ll, 4);
while(members == NULL)
{
fprintf(stderr, "malloc error: %s!!\n", strerror(errno));
members = (char *)malloc(pos*sizeof(char));
}
while(message == NULL)
{
fprintf(stderr, "malloc error: %s!!\n", strerror(errno));
message = (char *)malloc(len*sizeof(char));
}
bzero(members, pos);
bzero(message, len);
RecvData(sockfd, meeting_name, 40);
RecvData(sockfd, members, pos);
RecvData(sockfd, message, len);
printf("members: %s\n", members);
printf("message: %s\n", message);
int i;
for(i = 0; i < pos; i+= 20)
{
bzero(&buf_online, sizeof(buf_online));
memcpy(buf_online.username, &members[i], 20);
semop_ret=semop(sem_id, &semwait, 1);
if(search_online_member(&buf_online, shmid_hash_table, shmid_empty_list, shmid_online_table) == -1)
{
printf("can't find member!!\n");
semop(sem_id, &semsignal, 1);
continue;
}
semop(sem_id, &semsignal, 1);
if(buf_online.pid == getpid())
{
ptask = NULL;
ptask = (task_t*)malloc(sizeof(task_t));//安全分配内存
if (ptask == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask == NULL)
{
ptask = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask, sizeof(task_t));
memcpy(ptask->head, head, 64);
memcpy(ptask->buffer, meeting_name, 40);
if(len > 0)
memcpy(&ptask->buffer[40], message, len);
ptask->fd = buf_online.fd;
ev.data.ptr = ptask;
ev.events = EPOLLOUT|EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, ptask->fd, &ev);
}
else
{
sprintf(path, "%s%d", PATH, buf_online.pid);
//printf("436 transfer pid: %d, this pid %d, path: %s\n", buf_online.pid, getpid(), path);
//int unixd_len = strlen(unixd_addr.sun_path)+sizeof(unixd_addr.sun_family);
int unixd_sockfd_transfer = 0;
struct sockaddr_un unixd_addr_transfer;
bzero(&unixd_addr_transfer,sizeof(unixd_addr_transfer));
strcpy(unixd_addr_transfer.sun_path, path);
unixd_addr_transfer.sun_family = AF_UNIX;
unixd_sockfd_transfer = socket(AF_UNIX,SOCK_DGRAM,0);
if(unixd_sockfd_transfer < 0)
{
perror("socket error");
exit(-1);
}
int unixd_len_transfer = strlen(unixd_addr_transfer.sun_path)+sizeof(unixd_addr_transfer.sun_family);
sendto(unixd_sockfd_transfer, head, HEADLENGTH, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);
sendto(unixd_sockfd_transfer, meeting_name, 40, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);
if(len > 0)
sendto(unixd_sockfd_transfer, message, len, 0, (struct sockaddr*)&unixd_addr_transfer, unixd_len_transfer);
//***********************在相应进程的域套接字接收在进行转发************
}
}
char logpath[120];
bzero(logpath, 120);
sprintf(logpath, "./log/meeting/meeting_log_%s", meeting_name);
int logfd = open(logpath, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
if (logfd < 0)
{
fprintf(stderr, "open log error: %s!!\n", strerror(errno));
}
else
{
memcpy(&head[42], &len, 4);
WriteData(logfd, head, 64);
WriteData(logfd, message, len);
close(logfd);
}
bzero(head, 64);
free(members);
free(message);
members = NULL;
message = NULL;
}
else if(strncmp(head, "MH", 2) == 0)
{
/*int meetingfd = open("./log/meeting/meeting");
if(meetingfd < 0)
{
fprintf(stderr, "open log error %s\n", strerror(errno));
continue;
}*/
ptask = NULL;
ptask = (task_t*)malloc(sizeof(task_t));//安全分配内存
if (ptask == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask == NULL)
{
ptask = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask, sizeof(task_t));
memcpy(ptask->head, head, 64);
ptask->fd = sockfd;
ev.data.ptr = ptask;
ev.events = EPOLLOUT | EPOLLET;
//修改sockfd上要处理的事件为EPOLLOUT
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
}
else if(strncmp(head, "ML", 2) == 0)
{
char meeting_name[40];
bzero(meeting_name, 40);
RecvData(sockfd, meeting_name, 40);
ptask = NULL;
ptask = (task_t*)malloc(sizeof(task_t));//安全分配内存
if (ptask == NULL)
{
fprintf(stderr, "malloc error : %s!!\n", strerror(errno));
while(ptask == NULL)
{
ptask = (task_t*)malloc(sizeof(task_t));
}
}
bzero(ptask, sizeof(task_t));
memcpy(ptask->head, head, 64);
memcpy(ptask->buffer, meeting_name, 40);
ptask->fd = sockfd;
ev.data.ptr = ptask;
ev.events = EPOLLOUT | EPOLLET;
//修改sockfd上要处理的事件为EPOLLOUT
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
}
}
else if(events[i].events & EPOLLOUT) // 如果有数据发送
{
sockfd = ((task_t*)(events[i].data.ptr))->fd;
ptask = (task_t*)events[i].data.ptr;
printf("593 send msglength:%d, head[42] :%s\n", msg_length, &head[42]);
memcpy(&msg_length, &ptask->head[42], 4);
if(strncmp(ptask->head, "ML", 2) == 0)
{
char log_path[120], member_path[120];
bzero(log_path, 120);
bzero(member_path, 120);
sprintf(log_path, "./log/meeting/meeting_log_%s", ptask->buffer);
sprintf(member_path, "./log/meeting/meeting_member_%s", ptask->buffer);
printf("meeting name: %s\n", ptask->buffer);
int l_fd, m_fd;
if((l_fd = open(log_path, O_RDONLY)) < 0)
{
fprintf(stderr, "log error: %s\n", strerror(errno));
}
else if((m_fd = open(member_path, O_RDONLY)) < 0)
{
fprintf(stderr, "log error: %s\n", strerror(errno));
}
else
{
int m_len, l_len;
if((m_len = lseek(m_fd, 0, SEEK_END)) < 0)
{
fprintf(stderr, "lseek file log error: %s\n", strerror(errno));
}
char *m_buf = (char *)malloc(m_len*sizeof(char));
while(m_buf == NULL)
{
fprintf(stderr, "malloc error: %s!!\n", strerror(errno));
m_buf = (char *)malloc(m_len*sizeof(char));
}
if(lseek(m_fd, 0, SEEK_SET) < 0)
{
fprintf(stderr, "lseek file log error: %s\n", strerror(errno));
}
ReadData(m_fd, m_buf, m_len);
if((l_len = lseek(l_fd, 0, SEEK_END)) < 0)
{
fprintf(stderr, "lseek file log error: %s\n", strerror(errno));
}
char *l_buf = (char *)malloc(l_len*sizeof(char));
while(l_buf == NULL)
{
fprintf(stderr, "malloc error: %s!!\n", strerror(errno));
l_buf = (char *)malloc(l_len*sizeof(char));
}
if(lseek(l_fd, 0, SEEK_SET) < 0)
{
fprintf(stderr, "lseek file log error: %s\n", strerror(errno));
}
ReadData(l_fd, l_buf, l_len);
memcpy(&ptask->head[42], &m_len, 4);
memcpy(&ptask->head[46], &l_len, 4);
WriteData(ptask->fd, ptask->head, 64);
WriteData(ptask->fd, ptask->buffer, 40);
WriteData(ptask->fd, m_buf, m_len);
WriteData(ptask->fd, l_buf, l_len);
free(m_buf);
free(l_buf);
m_buf = NULL;
l_buf = NULL;
/////////////
}
close(l_fd);
close(m_fd);
}
else if(strncmp(ptask->head, "MH", 2) == 0)
{
int meetingfd = open("./log/meeting/meeting", O_RDONLY);
if(meetingfd < 0)
{
fprintf(stderr, "open log error %s\n", strerror(errno));
continue;
}
int log_len;
if((log_len = lseek(meetingfd, 0, SEEK_END)) < 0)
{
fprintf(stderr, "lseek file log error: %s\n", strerror(errno));
}
char *log_buf = (char*)malloc(log_len*sizeof(char));
while(log_buf == NULL)
{
fprintf(stderr, "malloc error :%s\n", strerror(errno));
log_buf = (char*)malloc(log_len*sizeof(char));
}
if(lseek(meetingfd, 0, SEEK_SET) < 0)
{
fprintf(stderr, "lseek file log error: %s\n", strerror(errno));
free(log_buf);
continue;
}
int count = log_len/40, i;
for(i = 0; i < count; i++)
ReadData(meetingfd, &log_buf[i*40], 40);
memcpy(&ptask->head[42], &log_len, 4);
SendData(ptask->fd, ptask->head, 64);
SendData(ptask->fd, log_buf, log_len);
free(log_buf);
log_buf = NULL;
}
else if(strncmp(ptask->head, "HF", 2) == 0)
{
char file_path[100];
strncpy(file_path, ptask->buffer, 100);
bzero(ptask->buffer, 100);
int file_log = open(file_path, O_RDONLY);
//printf("HF ptask->head : %s", ptask->head);
if(file_log < 0)
{
fprintf(stderr, "open file log error: %s\n", strerror(errno));
}
else
{
int file_len;
if((file_len = lseek(file_log, 0, SEEK_END)) < 0)
{
fprintf(stderr, "lseek file log error: %s\n", strerror(errno));
}
//printf("file_log len %d\n", file_len);
char *file_buf = NULL;
file_buf = (char*)malloc(file_len*sizeof(char));
while(file_buf == NULL)
{
file_buf = (char*)malloc(file_len*sizeof(char));
}
//printf("after malloc!!\n");
if(lseek(file_log, 0, SEEK_SET) < 0)
{
fprintf(stderr, "lseek file log error: %s\n", strerror(errno));
}
int count = 0;
while(1)
{
if(ReadData(file_log, &file_buf[count], 104) == -1)
break;
count += 104;
//printf("count = %d\n", count);
if (count == file_len)
break;
}
//printf("after read!!\n");
memcpy(&ptask->head[42], &file_len, 4);
SendData(ptask->fd , ptask->head, 64);
SendData(ptask->fd, file_buf, file_len);
free(file_buf);
close(file_log);
}
}
else if(strncmp(ptask->head, "FD", 2) == 0)
{
int pos, len;
memcpy(&len, &ptask->head[42], 4);
memcpy(&pos, &ptask->head[46], 4);
char receiver[20], file_name[30];
bzero(receiver, 20);
bzero(file_name, 30);
strncpy(receiver, &ptask->head[22], 20);
memcpy(file_name, &ptask->head[50], 14);
memcpy(&file_name[14], &ptask->buffer, 16);
char file_path[100];
bzero(file_path, 100);
sprintf(file_path, "./log/file/%s/%s", receiver, file_name);
int fd = open(file_path, O_RDONLY);
if(fd == -1)
{
fprintf(stderr, "read file: %s error: %s\n", file_path, strerror(errno));
bzero(head, 64);
continue;
}
else
{
//bzero(ptask, sizeof(task_t));
if(lseek(fd, pos, SEEK_SET) == -1)
{
fprintf(stderr,"lseek error: %s\n", strerror(errno));
}
else
{
int add_len;
char file_buffer[MAXLINE*10];
bzero(file_buffer, MAXLINE*10);
add_len = read(fd, file_buffer, MAXLINE*10);
//printf("add_len: %d\n", add_len);
len += add_len;
printf("len : %d\n", len);
memcpy(&ptask->head[42], &len, 4);
int head_len = send(sockfd, ptask->head, HEADLENGTH, 0);
int buf_len = send(sockfd, ptask->buffer, msg_length, 0);
int file_len = send(sockfd, file_buffer, add_len, 0);
//printf("head_len: %d, buf_len: %d,send file_len %d!!\n", head_len, buf_len, file_len);
}
close(fd);
}
}
else
{
int send_len = send(sockfd, ptask->head, HEADLENGTH, 0);
printf("send len: %d, : head %s\n", send_len, ptask->head);
if(msg_length != 0)
{
int buf_len = send(sockfd, ptask->buffer, msg_length, 0);
printf("send sock is %d, buf_len is %d, data is : %s\n", ptask->fd, buf_len, ptask->buffer);
}
//设置用于读操作的文件描述符
if(strncmp(ptask->head, "IM", 2) == 0)
{
write_chatlog_r(ptask->head, ptask->buffer);//写接收者的聊天日志
}
}
ev.data.fd =sockfd;
//设置用于注测的读操作事件
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
printf("free: %d\n", ptask);
if(ptask != NULL)
free(ptask);
else
fprintf(stderr, "free error: %s!!\n", strerror(errno));
ptask = NULL;
bzero(head, 64);
//sleep(2);
}
}
}
return 0;
}

浙公网安备 33010602011771号