纯C语言,聊天软件服务端、客户端

下载地址:


功能:

客户端输入帐号、密码,发送给服务端,服务端读取本地文件验证是否正确。若正确,则保存客户端信息到链表,则客户端上线。

客户端输入目标客户端帐号,可发送信息给该客户端。


写的比较好的地方:

char data[]={"-name+message"};

提取name、message:

char name[1024]={'\0'},message[1024]={'\0'};

strcpy(message,strchr(data,'+')+1); //提取message

*strchr(data,'+') = '\0';

strcpy(name,strchr(data,'-')+1); //提取name


实现截图:

纯C语言,聊天软件服务端、客户端


伪代码

服务端:

1、创建线程,处理数据链表

while(1)

{

    2、等待客户端连接,创建线程,处理客户端文件描述符

}


        2.1、验证登录,保存帐号信息到帐号信息链表

        2.2、while(1)

                {

                        接收客户端数据:若为命令,则处理命令;若为传输数据则保存数据到数据链表尾

                }

        1.1、循环读取数据链表头,解析数据,发送到对应客户端



客户端

1、发送帐号、密码等待服务端验证通过

2、创建线程:心跳包

3、创建线程接收服务端数据

4、while(1)

    {

        处理输入,并发送数据

    }


另一个写的比较好的地方,单向链表LinkListOfClass代码:

#include <stdlib.h>

#ifndef LINK_LIST_OfClass_H
#define LINK_LIST_OfClass_H



//全局替换OfClass,即可用于新链表
/*
elemTypeOfClass 				链表元素类型 的结构体类型
linkListNodeOfClass 		链表元素类型
linkListOfClass					链表类型

linkListOfClass* LinkListOfClass_Init()			//初始化链表											
LinkListNodeOfClass* LinkListOfClass_MakeNode(elemTypeOfClass tempElem)			//生成节点	
void LinkListOfClass_Destroy(linkListOfClass *tempLinkList)			//释放链表	
void LinkListOfClass_InsertFirst(linkListOfClass *tempLinkList,linkListNodeOfClass *tempLinkList_Node)			//链表头插入节点
void LinkListOfClass_DeleteFirst(linkListOfClass *tempLinkList)			//删除链表头节点	
void LinkListOfClass_InsertEnd(linkListOfClass *tempLinkList,linkListNodeOfClass *tempLinkList_Node)			//链表尾删除节点	
int LinkListOfClass_DeleteEnd(linkListOfClass *tempLinkList)			//删除链表尾节点	
void LinkListOfClass_TrvlFunc(linkListOfClass *tempLinkList,void *Function_element(elemTypeOfClass tempElem))			//遍历链表,对每个节点执行函数
void LinkListOfClass_TrvlSingleFunc(linkListOfClass *tempLinkList,char* name,void *Function_element(elemTypeOfClass* tempElem))			//遍历链表,对指定节点执行函数	
void LinkListOfClass_TrvlDelNode(linkListOfClass *tempLinkList,char* name)			//遍历链表,删除指定节点	

void FreeNodeOfClass(LinkListNodeOfClass *tempLinkList_Node)			//释放节点
*/



typedef struct ElementOfClass		//链表元素类型 的结构体类型
{
	char name[1024];
	int client_socket;
	int state;
}elemTypeOfClass;

//#define elemType struct struct_element		//链表元素类型

typedef struct LinkListNodeOfClass		//节点类型
{
	elemTypeOfClass *elem;			//元素,影响elemTypeOfClass定义
	struct LinkListNodeOfClass *next;
}linkListNodeOfClass;

typedef struct LinkListOfClass		//链表类型
{
	linkListNodeOfClass *head,*tail;			//头尾节点地址
	int length;
}linkListOfClass;

/***************************************
*函数名:MakeNodeOfClass
*函数功能描述:初始化节点
*函数参数:
elemTypeOfClass tempElem				————>节点元素
*函数返回值:节点指针
*作者:庞一江
*函数创建日期 :
***************************************/
LinkListNodeOfClass* LinkListOfClass_MakeNode(elemTypeOfClass tempElem)
{
	LinkListNodeOfClass *tempLinkList_Node=(LinkListNodeOfClass*)malloc(sizeof(LinkListNodeOfClass));
	tempLinkList_Node->elem=(elemTypeOfClass *)malloc(sizeof(elemTypeOfClass));
	*(tempLinkList_Node->elem)=tempElem;
	return tempLinkList_Node;
}
/***************************************
*函数名:FreeNodeOfClass
*函数功能描述:释放节点
*函数参数:
struct LinkList_Node *tempLinkList_Node				————>节点指针
*函数返回值:
*作者:庞一江
*函数创建日期 :
***************************************/
void FreeNodeOfClass(LinkListNodeOfClass *tempLinkList_Node)
{
	free(tempLinkList_Node->elem);
	free(tempLinkList_Node);
}
/***************************************
*函数名:LinkList_Init
*函数功能描述:链表初始化
*函数参数:
*函数返回值:链表指针
*作者:庞一江
*函数创建日期 :
***************************************/
linkListOfClass* LinkListOfClass_Init()
{
	linkListOfClass *tempLinkList=(linkListOfClass*)malloc(sizeof(linkListOfClass));
	tempLinkList->tail=NULL;
	tempLinkList->head=tempLinkList->tail;
	tempLinkList->length=0;
	return tempLinkList;
}
/***************************************
*函数名:LinkList_Destroy
*函数功能描述:
*函数参数:
struct LinkList *tempLinkList				————>链表指针
*函数返回值:
*作者:庞一江
*函数创建日期 :
***************************************/
void LinkListOfClass_Destroy(linkListOfClass *tempLinkList)
{
	//需要释放每个节点
	free(tempLinkList);
}
/***************************************
*函数名:LinkListOfClass_InsertFirst
*函数功能描述:在链表头插入节点
*函数参数:
struct LinkList *tempLinkList				————>链表指针
struct LinkList_Node *tempLinkList_Node				————>节点指针
*函数返回值:
*作者:庞一江
*函数创建日期 :
***************************************/
void LinkListOfClass_InsertFirst(linkListOfClass *tempLinkList,linkListNodeOfClass *tempLinkList_Node)
{
	//原链表不为空
	if(tempLinkList->head!=NULL)	
	{
		tempLinkList_Node->next=tempLinkList->head;
		tempLinkList->head=tempLinkList_Node;
	}
	//原链表为空,则head、tail都需初始化
	else	
	{
		tempLinkList_Node->next=NULL;
		tempLinkList->head=tempLinkList_Node;
		tempLinkList->tail=tempLinkList_Node;
	}
	//链表长度加1
	tempLinkList->length++;
}
/***************************************
*函数名:LinkListOfClass_DeleteFirst
*函数功能描述:删除链表头节点
*函数参数:
struct LinkList *tempLinkList				————>链表指针
*函数返回值:
*作者:庞一江
*函数创建日期 :
***************************************/
void LinkListOfClass_DeleteFirst(linkListOfClass *tempLinkList)
{
	//当链表不为空
	if(tempLinkList->head!=NULL)
	{
		linkListNodeOfClass *tempNode=tempLinkList->head;
		tempLinkList->head=tempNode->next;
		if(tempNode->next==NULL)	//原链表只有一个节点,那么tail也需修改
		{
			tempLinkList->tail=tempNode->next;
		}
		tempLinkList->length--;			//链表长度减1
		FreeNodeOfClass(tempNode);	//释放节点内存
	}
	else
	{
		printf("链表为空\n");
	}
}
/***************************************
*函数名:LinkListOfClass_InsertEnd
*函数功能描述:链表尾插入节点
*函数参数:
struct LinkList *tempLinkList				————>链表指针
struct LinkList_Node *tempLinkList_Node				————>节点指针
*函数返回值:
*作者:庞一江
*函数创建日期 :
***************************************/
void LinkListOfClass_InsertEnd(linkListOfClass *tempLinkList,linkListNodeOfClass *tempLinkList_Node)
{
	linkListNodeOfClass *tempNode=tempLinkList->tail;
	//原链表不为空
	if(tempLinkList->head!=NULL)	
	{
		tempNode->next=tempLinkList_Node;
		tempLinkList_Node->next=NULL;
		tempLinkList->tail=tempLinkList_Node;		
	}
	//原链表为空,则head、tail都需初始化
	else
	{
		tempLinkList_Node->next=NULL;
		tempLinkList->head=tempLinkList_Node;
		tempLinkList->tail=tempLinkList_Node;		
	}
	//链表长度加1
	tempLinkList->length++;
}
/***************************************
*函数名:
*函数功能描述:
*函数参数:
*函数返回值:
*作者:庞一江
*函数创建日期 :
***************************************/
int LinkListOfClass_DeleteEnd(linkListOfClass *tempLinkList)
{
	//单向链表,在不遍历链表的情况下,无法删除尾节点
}


//节点处理函数指针:打印
void *printf_element(elemTypeOfClass tempElem)
{
	printf("tempElem->name=%s\n",tempElem.name);
	printf("tempElem->client_socket=%d\n",tempElem.client_socket);
	printf("tempElem->state=%d\n",tempElem.state);
}
//节点处理函数指针:state置1
void *state1_element(elemTypeOfClass* tempElem)
{
	tempElem->state = 1;
}
//节点处理函数指针:state置0
void *state0_element(elemTypeOfClass* tempElem)
{
	tempElem->state = 0;
}
/***************************************
*函数名:LinkList_Traverse
*函数功能描述:遍历链表,对每个节点元素进行 函数处理(printf_pyj)
*函数参数:
struct LinkList *tempLinkList				————>链表指针
void *printf_pyj(elemType tempElem)				————>处理函数指针
*函数返回值:
*作者:庞一江
*函数创建日期 :
***************************************/
void LinkListOfClass_TrvlFunc(linkListOfClass *tempLinkList,void *Function_element(elemTypeOfClass tempElem))
{
	linkListNodeOfClass *tempNode=tempLinkList->head;
	//当链表不为空
	if(tempLinkList->head!=NULL)
	{
		while(1)
		{
			if(tempNode->next!=NULL)
			{
				Function_element(*(tempNode->elem));
				tempNode=tempNode->next;			
			}
			else
			{
				Function_element(*(tempNode->elem));
				break;
			}
		}
	}
	else
	{
		printf("链表为空\n");
	}
}
/***************************************
*函数名:
*函数功能描述:遍历链表,对制定name节点元素进行 函数处理
*函数参数:
*函数返回值:
*作者:庞一江
*函数创建日期 :
***************************************/
void LinkListOfClass_TrvlSingleFunc(linkListOfClass *tempLinkList,char* name,void *Function_element(elemTypeOfClass* tempElem))
{
	linkListNodeOfClass *tempNode=tempLinkList->head;
	//当链表不为空
	if(tempLinkList->head!=NULL)
	{
		while(1)
		{
			if(tempNode->next!=NULL)
			{
				if(strcmp(name,(*(tempNode->elem)).name) == 0)
					{
						Function_element(tempNode->elem);
						break;
					}
				else
				 tempNode=tempNode->next;			
			}
			else
			{
				if(strcmp(name,(*(tempNode->elem)).name) == 0)
					{
						Function_element(tempNode->elem);
					}
				break;
			}
		}
	}
	else
	{
		printf("链表为空\n");
	}
}

/***************************************
*函数名:
*函数功能描述:遍历链表,根据name,返回socket
*函数参数:
*函数返回值:
*作者:庞一江
*函数创建日期 :
***************************************/
int LinkListOfClass_TrvlReturnSocket(linkListOfClass *tempLinkList,char* name)
{
	linkListNodeOfClass *tempNode=tempLinkList->head;
	//当链表不为空
	if(tempLinkList->head!=NULL)
	{
		while(1)
		{
			if(tempNode->next!=NULL)
			{
				if(strcmp(name,(*(tempNode->elem)).name) == 0)
					{
						if((*(tempNode->elem)).state == 1)
							return 0;
						else
							return (*(tempNode->elem)).client_socket;
					}
				else
				 tempNode=tempNode->next;			
			}
			else
			{
				if(strcmp(name,(*(tempNode->elem)).name) == 0)
					{
						if((*(tempNode->elem)).state == 1)
							return 0;
						else
							return (*(tempNode->elem)).client_socket;
					}
				return -1;
			}
		}
	}
	else
	{
		printf("链表为空\n");
		return -1;
	}
}

/***************************************
*Function:
*Description:遍历链表,根据name,删除节点
*Parameters:
*Return:
*Writer:庞一江
*Date:
***************************************/
void LinkListOfClass_TrvlDelNode(linkListOfClass *tempLinkList,char* name)
{
	linkListNodeOfClass *tempNode = tempLinkList->head;
	linkListNodeOfClass *tempLastNode = NULL;
	//当链表不为空
	if(tempLinkList->head!=NULL)
	{
		while(1)
		{
			if(tempNode->next!=NULL)
			{
				if(strcmp(name,(*(tempNode->elem)).name) == 0)
					{
						if(tempLastNode == NULL) 
							tempLinkList->head = tempNode->next;
						else
							tempLastNode->next = tempNode->next;
						FreeNodeOfClass(tempNode);	//释放节点内存
						break;
					}
				else
					{
						tempLastNode = tempNode;
						tempNode = tempNode->next;	
					}
			}
			else
			{
				if(strcmp(name,(*(tempNode->elem)).name) == 0)
					{
						if(tempLastNode == NULL)
							{
								tempLinkList->head = NULL;
								tempLinkList->tail = NULL;
								tempLinkList->length = 0;
							}
						else
							{
								tempLastNode->next = NULL;
								tempLinkList->tail = tempLastNode;
							}
						FreeNodeOfClass(tempNode);	//释放节点内存
					}
				break;
			}
		}
	}
	else
	{
		printf("链表为空\n");
	}
}

#endif


;