#include
#include
#include
#include
#include
#include
//#include
#include
#include
//服务器和客户端间发送的内容结构体
struct msg_t
{
char name[32];
char text[256];
};
struct client_t//双向链表
{
int fd;
struct client_t *next;
struct client_t **prev;//前驱
};
//全局变量
struct client_t *head=NULL;
void *child_proc (void *arg)
{
int fd=(int)arg;
struct msg_t msg;
int ret;
struct client_t *p;
while (1)
{
bzero(&msg,sizeof(msg));
ret=recv(fd,&msg,sizeof(msg),0);
if(ret<0)
{
break;
}
if(ret==0)
{
continue;
}
if(strcmp(msg.text,“quit”)0)
{
break;
}
for(p=head;p!=NULL;p=p->next)
{
send(p->fd,&msg,sizeof(msg),0);
}
}
//遍历链表,移除节点
for(p=head;p!=NULL;p=p->next)
{
if(fdp->fd)//找到该节点
{
*(p->prev)=p->next;//让他前一个的后一个指向自己的下一个
if(p->next!=NULL)//如果是NULL,则删除的是最后一个,不用动
{
p->next->prev=p->prev;//p的下一个的前一个指向p的前一个
free§;
}
}
}
close(fd);
return NULL;
}
int main()
{
int listen_fd;//fd 打开一些设备或者资源 核心结构体(代表文件资源)file descript 文件描述符
int conn_fd;//conn ->connection
struct sockaddr_in saddr,caddr;//socketip
int ret;//ret ->return 接受返回值
int len;//len ->length 长度
pthread_t tid;
struct client_t *node;//初始化函数
printf("Next socket...n");
listen_fd=socket(AF_INET,SOCK_STREAM,0);//(使用IP协议,TCP协议,)//SOCK_STREAM<==>tcp协议 //创建套接字,用于监听
if(listen_fd<0)//创建失败
{
printf("Socket failedn");
return -1;
}
bzero(&saddr,sizeof(saddr));//清空saddr
saddr.sin_family=AF_INET;//family代表所用协议为ip协议
saddr.sin_addr.s_addr=htonl(INADDR_ANY);//htonl函数 参数代表本机全部地址
saddr.sin_port=htons(8888);//端口 1025-65535
printf("Next bind...n");
ret=bind(listen_fd,(struct sockaddr*)&saddr,sizeof(saddr));//bind函数 端口绑定
if(ret<0)
{
printf("bind errorn");
close(listen_fd);//释放资源
return -1;
}
printf("Next listen...n");
ret=listen(listen_fd,10);//5-随意长度 设置最大监听客户端数量
if(ret<0)
{
printf("listen errorn");
close(listen_fd);
return -1;
}
bzero(&caddr,sizeof(caddr));//清空caddr
len=sizeof(caddr);//caddr的长度赋值给len
printf("Next accept...n");
while(1)//死循环,保证服务器端不退出
{
conn_fd=accept(listen_fd,(struct sockaddr*)&caddr,&len);//阻塞等待客户端响应
if(conn_fd<0)//创建失败,所以还没有conn_fd资源
{
printf("accept errorn");
continue;
}
//保存链表
node=(struct client_t*)malloc(sizeof(struct client_t));//并分配内存,它多大分配多大,malloc返回void*
bzero(node,sizeof(struct client_t));
node->fd=conn_fd;
node->next=head;
node->prev=&head;
head=node;
pthread_create(&tid,NULL,&child_proc,(void *)conn_fd);//创建线程
}
close(listen_fd);
return 0;
}



