include <sys/types.h>#include <sys/socket.h>#include <stdio.h>#include <string.h>#include <arpa/inet.h>#include <netinet/in.h>#include <unistd.h>#include <pthread.h>#define MAX_CLT 5int clt_sfd[MAX_CLT] = {0};char clt_name[MAX_CLT][100] = {0};void *broadcast_clt(void *arg){
long index = (long)arg;int sfd = clt_sfd[index];int ret = -1;int i = 0;char buf[100] = {0};char welcome[100] = {0};char msg[100] = {0};while(1){ret = recv(sfd, buf, 100, 0);if((ret < 0) || (0 == ret)){clt_sfd[index] = 0;break;}if(0 == strncmp(buf, "quit", 4)){send(sfd, "quit", 5, 0);clt_sfd[index] = 0;break;}if(0 == strncmp(buf, "NAME", 4)){strcpy(clt_name[index], buf + 4);bzero(welcome, 100);sprintf(welcome, "Welcome %s!", clt_name[index]);for(i = 0; i < MAX_CLT; i++){if(clt_sfd[i] != 0){send(clt_sfd[i], welcome, 100, 0);}}}else{sprintf(msg, "%s: %s", clt_name[index], buf);for(i = 0; i < MAX_CLT; i++){if((clt_sfd[i] != 0) && (clt_sfd[i] != sfd)){send(clt_sfd[i], msg, 100, 0);}}}
usleep(1000);}close(sfd);pthread_exit(NULL);}int main(void){pthread_t broadcast_thread[MAX_CLT];long i = 0;int ret = -1;//int socket(int domain, int type, int protocol);int sfd = -1;int new_sfd = -1;sfd = socket(AF_INET, SOCK_STREAM, 0);//int bind(int sockfd, struct sockaddr *my_addr, int addrlen);struct sockaddr_in srv_addr;bzero(&srv_addr, sizeof(struct sockaddr_in));srv_addr.sin_family = AF_INET;srv_addr.sin_port = 6666;srv_addr.sin_addr.s_addr = 0; //服务器IP为0,表示本机IP,通用ret = bind(sfd, (struct sockaddr *)(&srv_addr), sizeof(struct sockaddr));//int listen(intsockfd, int backlog);ret = listen(sfd, 10);while(1){//int accept(int sockfd, struct sockaddr *addr, int *addrlen);int clt_addrlen = 0;struct sockaddr_in clt_addr;bzero(&clt_addr, sizeof(struct sockaddr_in));new_sfd = accept(sfd, (struct sockaddr *)(&clt_addr), &clt_addrlen);if(-1 == new_sfd){continue;}for(i = 0; i < MAX_CLT; i++){
if(0 == clt_sfd[i]){clt_sfd[i] = new_sfd;pthread_create(&broadcast_thread[i], NULL, broadcast_clt, (void *)i);pthread_detach(broadcast_thread[i]);break;}}}close(sfd);for(i = 0; i < MAX_CLT; i++){if(clt_sfd[i] > 0){close(new_sfd);}}return 0;}