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

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

 c语言socket简单聊天室基于linux环境_第1张图片

你可能感兴趣的:(C/C++)