cygwin+window+telnet测试环境
用于自己学习,里面很多用户输入会导致内存泄露,
仅仅用于个人练习
/**
* gdb调试命令
* gcc -g -o aaa aaa.c //-g参数调试的时候可以看到源代码,否则是内存地址
* b 设置断点
* s 下一步,进入方法
* n 下一步,不进入方法
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/** * 储存连接 * / struct clientList{ int connfd; struct clientList *next; }; /** * 保存用户名信息 * / struct minfo{ int connfd; char* name; }; typedef struct minfo Info; typedef struct clientList ClientList; /** * 储存连接,返回表头 * / ClientList* addClient(ClientList* list,ClientList* client); /** * 删除连接,返回表头 * / ClientList* removedClient(ClientList* list,int connfd); /** * 打印链表,用于调试 * / void show(ClientList* list, char* mes); /** * 按行读取连接内容,'\n'结束,中间忽略回车'\r' * / char* mreadline(int connfd); /** * 新开线程中处理的方法,用户分发每个用户消息 * / void m_turn(int connfd); /** * 全局变量,用于线程访问,储存所有当前的连接 * / ClientList* list = NULL; int main(int argc, char *argv[]) { int listenfd = 0; struct sockaddr_in serv_addr; char sendBuff[1025]; time_t ticks; listenfd = socket(AF_INET, SOCK_STREAM, 0); memset(&serv_addr, '\0', sizeof(serv_addr)); memset(sendBuff, '\0', sizeof(sendBuff)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(5000); bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); listen(listenfd, 10); while(1) { int connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); ClientList* client = (ClientList*)malloc(sizeof(ClientList)); client->connfd = connfd; client->next = NULL; printf("......%id\n",connfd); list = addClient(list,client); ticks = time(NULL); snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n please enter your name:", ctime(&ticks)); int ret = write(connfd, sendBuff, strlen(sendBuff)); if (ret<=0){ list = removedClient(list,connfd); continue; } pthread_t thread; pthread_create(&thread, NULL, m_turn, connfd); sleep(1); } } void m_turn(int connfd){ char* name = mreadline(connfd); if (name==NULL){ list = removedClient(list,connfd); return; } Info* info = (Info*)malloc(sizeof(Info)); info->connfd = connfd; info->name = name; char* wmes = (char*)malloc(1024); memset(wmes,'\0',1024); //snprintf(wmes, sizeof(wmes), "welcome %s\r\n",info->name); strcat(wmes,"welcome "); strcat(wmes,info->name); strcat(wmes,"\r\n"); int ret = write(info->connfd,wmes,strlen(wmes)); if(ret<=0){ list = removedClient(list,info->connfd); free(info); return; } while(1){ char* mes = mreadline(info->connfd); if (mes==NULL) { list = removedClient(list,info->connfd); free(info); return; } if (strcmp(mes,"exit")==0){ list = removedClient(list,info->connfd); free(info); return; } char *words = (char*)malloc(1024*10); memset(words,'\0',1024*10); strcat(words,info->name); strcat(words," say: "); strcat(words,mes); strcat(words,"\r\n"); ClientList* p = list; show(list,"new thread!"); while(1){ if (p->next!=NULL){ ret = write(p->connfd,words,strlen(words)); if(ret<=0){ list = removedClient(list,info->connfd); break; } p = p->next; }else{ ret = write(p->connfd,words,strlen(words)); if(ret<=0){ list = removedClient(list,info->connfd); } break; } } } free(info); } void show(ClientList* list, char* mes){ ClientList* p = list; if (p==NULL){ printf("this is nothing!\n"); return; }else{ while(1){ if(p->next!=NULL){ printf("-------------show id:%d.....%s\n",p->connfd,mes); p = p->next; } else{ printf("-------------show end id:%d.....%s\n",p->connfd,mes); break; } } } } ClientList* addClient(ClientList* list,ClientList* client){ ClientList* p = list; if(list==NULL){ list = client; }else{ while(1){ if(p->next!=NULL){ printf("---------id:%d\n",p->connfd); p = p->next; } else{ p->next = client; printf("---------id:%d\n",client->connfd); break; } } } show(list,"add"); return list; } ClientList* removedClient(ClientList* list,int connfd){ ClientList* p = list; ClientList* last = NULL; while(1){ if(p->next!=NULL){ if(p->connfd==connfd){ if(last){ last->next = p->next; close(connfd); free(p); break; }else{ close(connfd); list = p->next; free(p); break; } } last = p; p = p->next; }else{ if(last){ last->next = p->next; close(connfd); free(p); break; }else list = p->next; close(connfd); free(p); break; } } show(list,"removed"); return list; } char* mreadline(int connfd){ char* mes = (char*)malloc(1024*10); memset(mes,'\0',1024*10); char* temp = mes; char c; //memset(mes,'\0',1024*10); int ret; while((ret = read(connfd,&c,1))>0){ if(c=='\n') break; if(c!='\r'){ *temp = c; temp++; } } if(ret<=0){ //list = removedClient(list,connfd); return NULL; } *temp = '\0'; return mes; }