#include "node.h"
int main(int argc, char const *argv[])
{
printf("主程序运行\n");
chata K = (chata)malloc(sizeof(chatb));
// memset(K->name, 0, sizeof(K->name));
// memset(K->code, 0, sizeof(K->code));
// memset(K->chat, 0, sizeof(K->chat));
// memset(K->data, 0, sizeof(K->data));
doublelinks L =list_create();
links(L,K);
void list_free(doublelinks L, chata K);
free(K);
K = NULL;
return 0;
}
#include "node.h"
int links(doublelinks L,chata K)
{
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
int reuse = 1;
setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR,&reuse, sizeof(reuse));
printf("socket success sfd = %d\n", sfd);
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(SER_PORT);
sin.sin_addr.s_addr = inet_addr(SER_IP);
if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) ==-1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
struct sockaddr_in cin;
socklen_t len = sizeof(cin);
//使用poll完成多个阻塞任务的并发执行
struct pollfd pfd[2];
pfd[0].fd = 0; //表示检测0好文件描述符
pfd[0].events = POLLIN; //表示检测读事件
pfd[1].fd = sfd; //表示检测cfd文件描述符
pfd[1].events = POLLIN; //表示检测读事件
while(1){
int res = poll(pfd, 2, -1);
if(res == -1)
{
perror("poll error");
return -1;
}else if(res == 0)
{
printf("time out\n");
return -1;
}
//当程序执行至此,说明检测容器中有事件产生
if(pfd[1].revents == POLLIN){
char buf[1024];
recvfrom(sfd, buf,sizeof(buf),0,(struct sockaddr *)&cin, &len);
if(strncmp(buf, "link", 4) == 0){
sendto(sfd, "usrname:", 9, 0, (struct sockaddr *)&cin, len);
recvfrom(sfd, K -> name,16,0,(struct sockaddr *)&cin, &len);
sendto(sfd, "usrcode:", 9, 0, (struct sockaddr *)&cin, len);
recvfrom(sfd, K -> code,16,0,(struct sockaddr *)&cin, &len);
if(search(L,K) == 1){//*************这里为什么输入两次密码才有反应密码错误**********************
memcpy(K->data, &cin, sizeof(struct sockaddr_in));
printf(".....%s登录,目前聊天室共%d位用户......",K->name, L->len);
recvfrom(sfd,K->chat,1024,0,K->data, &len);
if(strcmp(K->chat, "quit") ==0){
break;
}
list_insert_head(L, K);
list_show(L, sfd);
freeks(K);
}
else{
sendto(sfd, "code error", 11, 0, (struct sockaddr *)&cin, len);
continue;
}
}else if(strncmp(buf, "delete",6) == 0){
freeks(K);
sendto(sfd, "usrname:", 9, 0, (struct sockaddr *)&cin, len);
recvfrom(sfd, K -> name,16,0,(struct sockaddr *)&cin, &len);
sendto(sfd, "usrcode:", 9, 0, (struct sockaddr *)&cin, len);
recvfrom(sfd, K -> code,16,0,(struct sockaddr *)&cin, &len);
if(search(L,K) == 1){
list_delete_head(L, K);
}
}else if(strncmp(buf, "zhuce",5) == 0){
freeks(K);
sendto(sfd, "usrname:", 9, 0, (struct sockaddr *)&cin, len);
recvfrom(sfd, K -> name,16,0,(struct sockaddr *)&cin, &len);
sendto(sfd, "usrcode:", 9, 0, (struct sockaddr *)&cin, len);
recvfrom(sfd, K -> code,16,0,(struct sockaddr *)&cin, &len);
list_insert_head(L, K);
memset(K ->name, 0, sizeof(K ->name));
memset(K ->code, 0, sizeof(K ->code));
}
}
if(pfd[0].revents == POLLIN){
char buf[1024];
fgets(buf, 1024, stdin);
buf[strlen(buf) - 1] = '\0';
doublelinks q = L->next;
while(1){
sendto(sfd, buf, 1024, 0, q->data, sizeof(q->data));
q = q->next;
if(q == NULL){
break;
}
}
}
}
close(sfd);
return 0;
}
void freeks(chata K){
memset(K->name, 0, sizeof(K->name));
memset(K->code, 0, sizeof(K->code));
memset(K->chat, 0, sizeof(K->chat));
memset(K->data, 0, sizeof(K->data));
}
int search(doublelinks L, chata K){//查找用户名和密码是否正确
doublelinks q = L->next;
int flag = 0;
while(q->next != NULL){
if((strcmp(q->name, K->name) == 0)&&(strcmp(q->code, K->code) == 0)){
flag = 1;
break;
}
q = q->next;
}
return flag == 1 ? 1 : 0;
}
//创建链表
doublelinks list_create(){
doublelinks L = (doublelinks)malloc(sizeof(Node));
if(L == NULL){
printf("L malloc error\n");
return NULL;
}
L->len = 0;
L->prio = NULL;
L->next = NULL;
return L;
}
//插入链表
int list_insert_head(doublelinks L, chata K){
if(NULL == L){
printf("所给链表不合法\n");
return -1;
}
doublelinks p = (doublelinks)malloc(sizeof(Node));
if(p == NULL){
printf("p malloc error\n");
return -1;}
strcpy(p->name,K->name);
strcpy(p->code,K->code);
strcpy(p->chat,K->chat);
strcpy(p->data,K->data);
p-> prio = NULL;
p->next = NULL;
//头插
if(L->next == NULL){
p->prio = L;
L->next = p;
}else{
p->prio = L;
p->next = L->next;
L->next->prio = p;
L->next = p;
}
L->len++;
printf("插入成功\n");
return 0;
}
//遍历链表
int list_show(doublelinks L,int sfd)
{
//判断逻辑
if(NULL==L || list_empty(L))
{
printf("遍历失败\n");
return ;
}
//定义遍历指针,将所有结点进行遍历
doublelinks q = L->next;
while(q != NULL && q->len%2 == 0)
{
// printf(".....%s发送:%s......\n",q->name,q->chat);
sendto(sfd, q->chat, 1024, 0, q->data, sizeof(q->data));
q = q->next;
}
printf("\n");
return 1;
}
int list_empty(doublelinks L){
return ( L->next == NULL);
}
int list_delete_head(doublelinks L, chata K)
{
//判断逻辑
if(NULL==L || list_empty(L))
{
printf("删除失败\n");
return -1;
}
//标记要删除的结点
doublelinks qq = L->next;
while(1){
if((strcmp(qq->name, K->name) == 0)&&(strcmp(qq->code, K->code) == 0)){
break;
}
qq = qq->next;
}
doublelinks p = qq;
//判断该结点是否是最后一个结点
if(p->next == NULL)
{
L->next = NULL;
}else
{
L->next = p->next;
p->next->prio = L;
}
//释放要删除的结点
free(p);
p = NULL;
//表长变化
L->len--;
printf("删除成功\n");
return 0;
}
void list_free(doublelinks L, chata K)
{
//判断逻辑
if(NULL == L)
{
printf("释放失败\n");
return;
}
//将所有结点释放
while(L->next != NULL)
{
list_delete_head(L, K);
}
//释放头结点
free(L);
L = NULL;
printf("释放成功\n");
}
#ifndef NODE_H
#define NODE_H
#include <myhead.h>
#define SER_PORT 8888
#define SER_IP "192.168.125.39"
typedef struct Node{
union{
char name[16];
char code[16];
char chat[1024];
struct sockaddr_in data[1024];
int len;
};
struct Node *prio;
struct Node *next;
}*doublelinks;Node;
typedef struct chatinfo{
char name[16];
char code[16];
char chat[1024];
struct sockaddr_in data[1024];
}*chata;chatb;
doublelinks list_create();
int links(doublelinks L, chata K);
int search(doublelinks L, chata K);
int list_insert_head(doublelinks L, chata K);
int list_empty(doublelinks L);
int list_delete_head(doublelinks L, chata K);
int list_show(doublelinks L, int sfd);
void list_free(doublelinks L, chata K);
void freeks(chata K);
#endif