c语言socket简单聊天室基于linux环境

这是一个基于Linux环境的C语言实现的简单聊天室,使用socket编程。文章提到在Cygwin上配合Windows进行telnet测试,但注意程序存在内存泄露问题,适合初学者进行练习。
摘要由CSDN通过智能技术生成

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; } 
             
            
           
          
         
       
      
      
     
     
    
    
   
   

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值