您的位置:首页 > 运维架构 > Linux

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

2014-01-18 21:59 351 查看
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;
}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息