C语言实现 聊天室小程序(带mysql数据库)

Ubuntu下编了一个小程序,写的不好不要见怪,优化可写评论区(随笔记录,共同进步,加油)

前提准备,Ubuntu有mysql,创建一个database命名为chat,并在其中建立一张命名为users的表。
C语言实现 聊天室小程序(带mysql数据库)_第1张图片
server.c代码段中的四个变量分别设置本机名,用户名,密码,数据库名
本机名用"localhost"、“127.0.0.1”、NULL都行

/*=============================================================*/
/**/const char *g_host_name = "localhost";
/**/const char *g_user_name = "root";
/**/const char *g_passwd = "";
/**/const char *g_db_name = "chat";
/*=============================================================*/

头文件中ip地址改成自己的ip

#define IPNET "192.168.218.136" //ip地址

效果图:(太多了,只截一张)
C语言实现 聊天室小程序(带mysql数据库)_第2张图片

头文件:
head.c

#ifndef _HEAD_H
#define _HEAD_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "mysql/mysql.h"

#define PORT 7093 //端口号
#define BACKLOG 50 //最大监听数量
#define MAXSIZE 1032 //消息msg的最大长度
#define IPNET "192.168.218.136" //ip地址
#define MAX_BUF_SIZE 1024 //数据库数组最大长度

#define MSG_ADD 1       //用户注册
#define MSG_CHANGE 2    //更改密码
#define MSG_LOGIN 3     //用户登录
#define MSG_LOGOUT 4    //用户退出
#define MSG_DATA 5  	//正常消息
#define MSG_ACK 6		//回复同意(正确)
#define MSG_UNACK 7 	//回复不同意(不正确)
#define MSG_PRIVATE 8	//私聊
#define MSG_GROUP 9		//群聊
#define MSG_FILE 10		//文件
#define MSG_NUM 11 		//在线人数
#define MSG_KICK 12     //踢人
#define MSG_MASTER 13   //群主
#define MSG_UNMASTER 14 //不是群主
#define MSG_PEOPLE 15
#define MSG_NONPEOPLE 16
#define MSG_FORBIDDEN 17
#define MSG_LIFT 18
//发送信息的结构体
struct msg
{
    int type; // 消息类型
    int data_len; // 数据长度
    char data[1024]; // 数据
};
//用户结构体
struct Login
{
	int state;
	char name[24];
	char passwd[20];
	char email[24];
};
#endif


服务器端:
server.c

#include "./head.h"

//数据库变量
MYSQL *g_conn; // mysql 链接
MYSQL_RES *g_res; // mysql 记录集
MYSQL_ROW g_row; // 字符串数组,mysql 记录行
/*=============================================================*/
/**/const char *g_host_name = "localhost";
/**/const char *g_user_name = "root";
/**/const char *g_passwd = "";
/**/const char *g_db_name = "chat";
/*=============================================================*/
char sql[MAX_BUF_SIZE];
char Time[MAX_BUF_SIZE];
struct Login login;
int iNum_rows = 0; // mysql 语句执行结果返回行数赋初值

//服务端变量
int fd;
int sockfd[50];
pthread_t tid[50]={0};
int len;
int startlen = 0;
int start = 1; //启动开关
int master_flag = 0;
int master_fd;
struct msg *rm,*sm;
struct sockaddr_in servaddr,cliaddr;
socklen_t cliaddr_len;
pid_t pid;
char Num[5];
//执行sql语句,成功返回0,失败返回-1
int executesql( const char * sql)
{

	if(mysql_real_query( g_conn , sql , strlen(sql) ) )
			return -1;
	return 0;
}
//初始化链接
int init_mysql()
{
	//init the database connection
	g_conn = mysql_init(NULL);
	//connection the database
	if( !mysql_real_connect( g_conn , g_host_name , g_user_name , g_passwd , g_db_name , 0 , NULL , 0 ) )
		return -1; //连接失败
	//检查是否可以使用
	if( executesql("set names utf8") )
		return -1; 
	return 0;//返回成功
}
//选择数据库,没有的时候创建
void create_database()
{
	sprintf(sql,"use chat;");
	if( executesql(sql) == -1 )
	{
		puts("create database");
		executesql("create database chat;");
		puts("choice database");
		executesql("use chat;");
		printf("success!");
	}
}
//查看表格完整性
void create_table()
{
	//user表的检查与创建
	sprintf(sql,"show tables;");
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res);
	if(iNum_rows == 0)
	{
		puts("create users table");
		executesql("create table users(name char(20) not null ,passwd char(24) not null ,email char(24) not null ,stat int(1) not null , fd int(1) not null);");
	}
	mysql_free_result(g_res); //释放结果集
}
//强制终止
void sigfun()
{
	int i;
	free(rm);
	free(sm);
	close(fd);
	exit(0);
}
//初始化服务器
void init_serv()
{
	rm=(struct msg*)malloc(MAXSIZE);
	sm=(struct msg*)malloc(MAXSIZE);
	// socket
	fd = socket( AF_INET , SOCK_STREAM , 0 );
	if( fd < 0 )
		perror("socket");
	bzero( &servaddr , sizeof(servaddr) );
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons( PORT );
	servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
	// bind
	if( bind( fd , (struct sockaddr *)&servaddr , sizeof(servaddr) ) < 0 )
		perror("bind");
	//listen
	if( listen( fd , BACKLOG ) < 0 )
		perror("listen");
	//对mysql进行初始化
	if(init_mysql())
		perror("init_mysql");
	//对数据库进行选择(没有则创建)
	create_database();
	//对表进行创建
	create_table();
}
//用户注册函数
void add_msg( int connfd )
{
	//告诉客户机可以进行注册(如果不允许注册,将MSG_ACK改成MSG_UNACK)
	sm->type = MSG_ACK;
	sm->data_len = 0;
	if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
		perror("send_add");
	while( 1 )
	{
		//接收来自客户端的帐号信息
		bzero( rm , sizeof( struct msg ));
		bzero( &login , sizeof( login ));
		len = recv( connfd , (void *)rm , MAXSIZE , 0 );
		if( len < 0 )
			perror("add_recv_len2");
		if( rm->type == MSG_DATA )
		{
			memcpy( login.name , rm->data , rm->data_len );
			//从数据库中找客户端输入的用户名
			sprintf( sql , "select * from users where name ='%s';",login.name);
			executesql(sql);
			//下面这两个函数一起使用,用于统计出现的个数
			g_res = mysql_store_result(g_conn);
			iNum_rows = mysql_num_rows(g_res);
			//如果没有出现过,告诉客户端可以使用
			if( iNum_rows == 0)
			{
				sm->type = MSG_ACK;
				sm->data_len = 0;
				if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
					perror("send_add");
			}
			//否则告诉客户端不可以使用
			else
			{
				sm->type = MSG_UNACK;
				sm->data_len = 0;
				if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
					perror("send_add");
				continue;
			}
		}
		//接收来自客户端的密码信息
		bzero( rm , sizeof( rm ));
		len = recv( connfd , (void *)rm , MAXSIZE , 0 );
		if( len < 0 )
			perror("add_recv_len2");
		if( rm->type == MSG_DATA )
		{
			memcpy( login.passwd , rm->data , rm->data_len ); 
			sm->type = MSG_ACK;
			sm->data_len = 0;
			if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
					perror("send_add");
		}
		//接收来自客户端的邮箱信息
		bzero( rm , sizeof( rm ));
		len = recv( connfd , (void *)rm , MAXSIZE , 0 );
		if( len < 0 )
			perror("add_recv_len2");
		if( rm->type == MSG_DATA )
		{
			memcpy( login.email , rm->data , rm->data_len ); 
			sm->type = MSG_ACK;
			sm->data_len = 0;
			if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
					perror("send_add");
			puts("name:");
			puts(login.name);
			puts("passwd:");
			puts(login.passwd);
			puts("email:");
			puts(login.email);
			//将帐号密码以及邮箱放入数据库,并将在线状态初始化为0(离线)
			sprintf(sql,"insert into users values('%s','%s','%s',%d,%d);",login.name,login.passwd,login.email,0,0);
			executesql(sql);
			puts("用户注册成功!");
			break;
		}
	}
}
//更改密码函数
void chg_msg( int connfd )
{
	//告诉客户机可以进行修改(如果不允许修改,将MSG_ACK改成MSG_UNACK)
	sm->type = MSG_ACK;
	sm->data_len = 0;
	if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
		perror("send_add");
	//接收来自客户端的帐号信息
	bzero( rm , sizeof( rm ));
	bzero( &login , sizeof( login ));
	len = recv( connfd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	if( rm->type == MSG_DATA )
	{
		memcpy( login.name , rm->data , rm->data_len );
		//从数据库中找客户端输入的用户名
		sprintf( sql , "select * from users where name ='%s';",login.name);
		executesql(sql);
		//下面这两个函数一起使用,用于统计出现的个数
		g_res = mysql_store_result(g_conn);
		iNum_rows = mysql_num_rows(g_res);
		//如果出现过,告诉客户端帐号存在
		if( iNum_rows != 0)
		{
			sm->type = MSG_ACK;
			sm->data_len = 0;
			if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add");
		}
		//否则告诉客户端不存在
		else
		{
			sm->type = MSG_UNACK;
			sm->data_len = 0;
			if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add");
			return;
		}
	}
	//接受来自客户端的邮箱信息
	bzero( rm , sizeof( rm ));
	len = recv( connfd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	if( rm->type == MSG_DATA )
	{
		memcpy( login.email , rm->data , rm->data_len );
		//从数据库中找客户端输入的用户名、邮箱
		sprintf( sql , "select * from users where name ='%s' and email = '%s';",login.name,login.email);
		executesql(sql);
		//下面这两个函数一起使用,用于统计出现的个数
		g_res = mysql_store_result(g_conn);
		iNum_rows = mysql_num_rows(g_res);
		//如果出现过,告诉客户端帐号邮箱匹配正确
		if( iNum_rows != 0 )
		{
			sm->type = MSG_ACK;
			sm->data_len = 0;
			if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add");
		}
		//否则告诉客户端不存在
		else
		{
			sm->type = MSG_UNACK;
			sm->data_len = 0;
			if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add");
			return;
		}
	}
	//接收客户端传来的新密码
	bzero( rm , sizeof( rm ));
	len = recv( connfd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
	perror("add_recv_len2");
	if( rm->type == MSG_DATA )
	{
		memcpy( login.passwd , rm->data , rm->data_len );
		puts("passwd:");
		//匹配帐号
		sprintf(sql,"update users set passwd = '%s' where name = '%s'",login.passwd,login.name);
        executesql(sql);
		puts("更改成功!");
	}
}
//在线人数查询
void num_people( int connfd )
{
	//从数据库中找在线人数
	sprintf( sql , "select * from users where stat = %d;",1);
	executesql(sql);
	//下面这两个函数一起使用,用于统计出现的个数
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res);
	sm->type = MSG_NUM;
	//将数字转换成字符串
	sprintf(Num,"%d",iNum_rows);
	sm->data_len = sizeof(Num);
	memcpy( sm->data , Num , sm->data_len );
	if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
		perror("send_add");
}
//私聊
void chat_private( int connfd ,char myname[24] )
{
	int i;
	int profd;
	char proName[24];
	char content[130]={0};
	//告诉客户机可以进行私聊(如果不允许修改,将MSG_ACK改成MSG_UNACK)
	sm->type = MSG_ACK;
	sm->data_len = 0;
	if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
		perror("send_add1");
	//接收来自客户端的用户信息
	bzero( rm , sizeof( rm ));
	len = recv( connfd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	memcpy( proName , rm->data , rm->data_len );
	printf("你输入的用户名:%s",proName);
	//从数据库中找客户端输入的用户名
	sprintf( sql , "select * from users where name ='%s' and stat = %d;",proName,1);
	executesql(sql);
	//下面这两个函数一起使用,用于统计出现的个数
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res);
	//如果用户存在并且在线,告诉客户端可以进行私聊
	if( iNum_rows != 0)
	{
		sm->type = MSG_PEOPLE;
		sm->data_len = 0;
		if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
			perror("send_add2");
	}
	//否则告诉客户端用户不存在(或已离线)
	else
	{
		sm->type = MSG_NONPEOPLE;
		sm->data_len = 0;
		if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
			perror("send_add3");
		return;
	}
	printf("开始查找!\n");
	sprintf( sql , "select * from users where stat = %d;",1);
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	while( (g_row = mysql_fetch_row(g_res) ) )
	{
		printf("%s\n",g_row[0]);
		if( strcmp( g_row[0] , proName ) == 0 )
		{
			printf("找到的用户名为:%s\n",g_row[0]);
			profd = atoi(g_row[4]);
			break;
		}
	}
	//接收用户发送过来的私聊信息
	bzero( rm , sizeof( rm ));
	len = recv( connfd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	if( rm->type == MSG_PRIVATE )
	{
		sprintf( content , "【私聊】%s say :",myname);
		strncat( content , rm->data , rm->data_len );
		//发送给对方
		bzero( sm , sizeof( sm ));
		sm->type = MSG_PRIVATE;
		sm->data_len = sizeof(content);
		memcpy( sm->data , content , sm->data_len );
		if( send( profd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
			perror("send_add4");
	}
}
//群聊
void chat_group( int connfd ,char myname[24] )
{
	int i;
	char content[130]={0};
	//告诉客户机可以进行群聊(如果不允许群聊,将MSG_ACK改成MSG_UNACK)
	sm->type = MSG_ACK;
	sm->data_len = 0;
	if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
		perror("send_add1");
	//接收用户发送过来的群聊信息
	bzero( rm , sizeof( rm ));
	len = recv( connfd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	if( rm->type == MSG_GROUP)
	{
		sprintf( content , "【群聊】%s say :",myname);
		strncat( content , rm->data , rm->data_len );
		//发送给所有人
		bzero( sm , sizeof( sm ));
		sm->type = MSG_GROUP;
		sm->data_len = sizeof(content);
		memcpy( sm->data , content , sm->data_len );
		//从数据库中查找
		sprintf( sql , "select * from users where stat = %d;",1);
		executesql(sql);
		g_res = mysql_store_result(g_conn);
		while( (g_row = mysql_fetch_row(g_res) ) )
		{
			if( send( atoi(g_row[4]) , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add2");
		}	
	}
}
//文件传输
void file_transfer( int connfd ,char myname[24] )
{

		//len = recv( connfd , (void *)rm , MAXSIZE , 0 );
			//if( len < 0 )
				//perror("recv");
		FILE *fp;
		fp = fopen("temp","a+");
		//fwrite(rm->data,sizeof(char),strlen(rm->data),fp);
		fprintf(fp,"%s",rm->data);
		fclose(fp);
		bzero( rm , sizeof(struct msg));
		//printf("%s 正在传文件\n",myname);

}
//踢人
void kick_people( int connfd )
{
	char kick_name[25]={0};
	int i,j,kickfd;
	if( connfd == master_fd ) //判断是否为群主
	{
		sm->type = MSG_MASTER;
	}
	else
		sm->type = MSG_UNMASTER;
	sm->data_len = 0;
	if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
		perror("send_add1");
	if( connfd == master_fd )
	{
		bzero( rm , sizeof( rm ));
		len = recv( connfd , (void *)rm , MAXSIZE , 0 );
		if( len < 0 )
			perror("add_recv_len2");
		if( rm->type == MSG_DATA )
		{
			memcpy( kick_name , rm->data , rm->data_len );
			sprintf( sql , "select * from users where name = '%s';",kick_name);
			executesql(sql);
			g_res = mysql_store_result(g_conn);
			while( (g_row = mysql_fetch_row(g_res) ) )
			{
				kickfd = atoi(g_row[4]);
			}
			bzero( sm , sizeof( sm ));
			sm->type = MSG_KICK;
			sm->data_len =0;
			if( send( kickfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add2");
			//将数据库中用户的在线状态设置为离线
			sprintf(sql,"update users set stat = %d where name = '%s'",0,kick_name);
    		executesql(sql);
			printf("用户%s已被踢出本群!\n",kick_name);
			
		}
	}
}
//禁言
void forbidden_people( int connfd )
{
    char forbidden_name[25]={0};
	int i,j,forbiddenfd;
	if( connfd == master_fd ) //判断是否为群主
	{
		sm->type = MSG_MASTER;
	}
	else
		sm->type = MSG_UNMASTER;
	sm->data_len = 0;
	if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
		perror("send_add1");
	if( connfd == master_fd )
	{
		bzero( rm , sizeof( rm ));
		len = recv( connfd , (void *)rm , MAXSIZE , 0 );
		if( len < 0 )
			perror("add_recv_len2");
		if( rm->type == MSG_DATA )
		{
			memcpy( forbidden_name , rm->data , rm->data_len );
			sprintf( sql , "select * from users where name = '%s';",forbidden_name);
			executesql(sql);
			g_res = mysql_store_result(g_conn);
			while( (g_row = mysql_fetch_row(g_res) ) )
			{
				forbiddenfd = atoi(g_row[4]);
			}
			bzero( sm , sizeof( sm ));
			sm->type = MSG_FORBIDDEN;
			sm->data_len =0;
			if( send( forbiddenfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add2");
			printf("用户%s已被禁言!\n",forbidden_name);
		}
	}
}
//解禁
void lift_a_ban( int connfd )
{
    char lift_name[25]={0};
	int i,j,liftfd;
	if( connfd == master_fd ) //判断是否为群主
	{
		sm->type = MSG_MASTER;
	}
	else
		sm->type = MSG_UNMASTER;
	sm->data_len = 0;
	if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
		perror("send_add1");
	if( connfd == master_fd )
	{
		bzero( rm , sizeof( rm ));
		len = recv( connfd , (void *)rm , MAXSIZE , 0 );
		if( len < 0 )
			perror("add_recv_len2");
		if( rm->type == MSG_DATA )
		{
			memcpy( lift_name , rm->data , rm->data_len );
			sprintf( sql , "select * from users where name = '%s';",lift_name);
			executesql(sql);
			g_res = mysql_store_result(g_conn);
			while( (g_row = mysql_fetch_row(g_res) ) )
			{
				liftfd = atoi(g_row[4]);
			}
			bzero( sm , sizeof( sm ));
			sm->type = MSG_LIFT;
			sm->data_len =0;
			if( send( liftfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add2");
			printf("用户%s已被解除禁言!\n",lift_name);
		}
	}
}
//用户注销
void cancellation_user( int connfd ,char myname[24] )
{
	int i,j;
	//告诉客户机可以进行注销
	sm->type = MSG_ACK;
	sm->data_len = 0;
	if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
		perror("send_add");
	//将数据库中用户的在线状态设置为离线
	sprintf(sql,"update users set stat = %d where name = '%s'",0,myname);
    executesql(sql);
	printf("用户%s已下线!\n",myname);
}
//聊天界面
void chat_menu( int connfd ,char myname[24] )
{
	int flag = 0;
	while( 1 )
	{
		bzero( rm , sizeof(struct msg));
		//接受来自客户端的请求
		len = recv( connfd , (void *)rm , MAXSIZE , 0 );
		if( len < 0 )
			perror("recv");
		switch( rm->type )
		{
			case 1:
						num_people(connfd); //在线人数查询
						break;
			case 2:
						chat_private(connfd,myname); //私聊
						break;
			case 3:
						chat_group(connfd,myname);//群聊
						break;
			case 4:
						file_transfer(connfd,myname);//文件传输
						break;
			case 5:
						kick_people(connfd);//踢人
						break;
			case 6:
						forbidden_people(connfd);//禁言
						break;
			case 7:
						lift_a_ban(connfd);//解禁
						break;
			case 0:
						cancellation_user(connfd,myname);//用户注销
						flag = 1;
						break;
		}
		if( flag == 1 )
		{
			printf("用户%s已退出!\n",myname);
			break;
		}
	}
}
//用户登录函数
void login_msg( int connfd )
{
	struct Login log;
	//告诉客户机可以进行登录(如果不允许登录,将MSG_ACK改成MSG_UNACK)
	sm->type = MSG_ACK;
	sm->data_len = 0;
	if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
		perror("send_add");
	//接收来自客户端的帐号信息
	bzero( &log , sizeof( log ));
	bzero( rm , sizeof( rm ));
	len = recv( connfd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	if( rm->type == MSG_DATA )
	{
		memcpy( log.name , rm->data , rm->data_len );
		//从数据库中找客户端输入的用户名
		sprintf( sql , "select * from users where name ='%s';",log.name);
		executesql(sql);
		//下面这两个函数一起使用,用于统计出现的个数
		g_res = mysql_store_result(g_conn);
		iNum_rows = mysql_num_rows(g_res);
		//如果出现过,告诉客户端帐号存在
		if( iNum_rows != 0)
		{
			sm->type = MSG_ACK;
			sm->data_len = 0;
			if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add");
		}
		//否则告诉客户端不存在
		else
		{
			sm->type = MSG_UNACK;
			sm->data_len = 0;
			if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add");
			return;
		}
	}
	//接收来自客户端的密码信息
	bzero( rm , sizeof( rm ));
	len = recv( connfd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	if( rm->type == MSG_DATA )
	{
		memcpy( log.passwd , rm->data , rm->data_len );
		//从数据库中找客户端输入的用户名、密码
		sprintf( sql , "select * from users where name ='%s' and passwd = '%s';",log.name,log.passwd);
		executesql(sql);
		//下面这两个函数一起使用,用于统计出现的个数
		g_res = mysql_store_result(g_conn);
		iNum_rows = mysql_num_rows(g_res);
		//如果出现过,告诉客户端密码正确
		if( iNum_rows != 0)
		{
			sm->type = MSG_ACK;
			sm->data_len = 0;
			if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add");
		}
		//否则告诉客户端密码不正确
		else
		{
			sm->type = MSG_UNACK;
			sm->data_len = 0;
			if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add");
			return;
		}
	}
	//接收用户发送过来的登录信号
	bzero( rm , sizeof( rm ));
	len = recv( connfd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	if( rm->type == MSG_LOGIN )
	{
		//从数据库中找客户端输入的用户名、密码
		sprintf( sql , "select * from users where name ='%s' and passwd = '%s' and stat = %d;",log.name,log.passwd,0);
		executesql(sql);
		//下面这两个函数一起使用,用于统计出现的个数
		g_res = mysql_store_result(g_conn);
		iNum_rows = mysql_num_rows(g_res);
		//如果出现过,告诉客户端可以进行登录
		if( iNum_rows == 1)
		{
			sm->type = MSG_ACK;
			sm->data_len = 0;
			if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add");
		}
		//否则告诉客户端用户登录已达上限
		else
		{
			sm->type = MSG_UNACK;
			sm->data_len = 0;
			if( send( connfd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add");
			return;
		}
	}
	printf("用户%s已经成功登录!\n",log.name);
	//将数据库用户在线状态设置为1(在线)
	sprintf(sql,"update users set stat = %d  where name = '%s'",1,log.name);
    executesql(sql);
	sprintf(sql,"update users set fd = %d  where name = '%s'",connfd,log.name);
    executesql(sql);
	if( master_flag == 0 )
	{
		master_flag = 1;
		master_fd = connfd;
	}
	//进入聊天界面
	chat_menu( connfd , log.name );
}
//菜单
void *server_receive( void *connfd )
{
	int flag = 0;
	while( 1 )
	{
		//接受来自客户端的请求
		bzero( rm , sizeof( rm ));
		len = recv( *(int *)connfd , (void *)rm , MAXSIZE , 0 );
		if( len < 0 )
			perror("recv");
		switch( rm->type )
		{
			case MSG_ADD:
						add_msg( *(int *)connfd ); //用户注册
						break;
			case MSG_CHANGE:
						chg_msg( *(int *)connfd ); //更改密码
						break;
			case MSG_LOGIN:
						login_msg( *(int *)connfd );//用户登录
						break;
			case MSG_LOGOUT:
						flag = 1;
						break;
		}
		if( flag == 1 )
		{
			//close( *(int *)arg );
			puts("客户端已退出!");
			break;
		}
	}
}
//线程创建
void serv_menu()
{
	int len;
	int ret;
	int i=0;
	int connfd;
	while( start && startlen < 50 )
	{
		cliaddr_len = sizeof(cliaddr);
		//accept
		connfd = accept( fd , (struct sockaddr *)&cliaddr , &cliaddr_len);
		if( -1 == connfd )
			perror("accept");
		//创建子进程
		ret = pthread_create(&tid[i++], NULL, server_receive, (void *)&connfd);
        if(0 != ret)
            perror("pthread_create");
        startlen++;
	}
}
int main(void)
{
	signal(SIGINT,sigfun);
	init_serv();
	serv_menu();
	return 0;
}

客户端:
client.c

#include "./head.h"

int master = 0;//1为群主,0为群员
int forbidden_flag = 0; //1为被禁言,0为没有被禁言
int lift_flag = 0; //1为被解禁,0为没有解禁
int non_people = 0; //1为没有找到此人
int fd;
int start = 1; //启动开关
int len;
int chat_flag = 0;
int pidchoice;
pthread_t tid;
struct sockaddr_in servaddr,cliaddr;
socklen_t addrlen,cliaddr_len;
struct msg *sm,*rm;
struct Login login;
char mypasswd[20]={0};
int kick = 0; //被踢(1)
//客户端强制退出
void sigfun()
{
	free(sm);
	free(rm);
	close(fd);
	exit(0);
}
//客户端一般退出
void close_cli()
{
	free(sm);
	free(rm);
	close(fd);
	exit(0);
}
//客户端初始化
void init_cli()
{
	//对信息进行初始化
	sm=(struct msg*)malloc(MAXSIZE);
	rm=(struct msg*)malloc(MAXSIZE);
	//socket
	fd = socket( AF_INET , SOCK_STREAM , 0 );
    if( fd < 0 )
		perror("socket error!");
	puts("socket success!");
    bzero( &servaddr , sizeof(servaddr) );
    servaddr.sin_family = AF_INET ;
    servaddr.sin_port = htons( PORT );
    servaddr.sin_addr.s_addr = inet_addr( IPNET );
	//connect
    if( connect( fd , (struct sockaddr *)&servaddr , sizeof(servaddr) ) < 0 )
		perror("connect error!");
	puts("connect success!");
}
//用户注册函数
void add_msg()
{
	getchar();
	//发送注册信号给服务器
	sm->type = MSG_ADD;
	sm->data_len = 0;
	if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
		perror("send_add");
	//接收来自服务器的回复
	len = recv( fd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	//服务器不允许注册
	if( rm->type == MSG_UNACK )
	{
		puts("目前不能进行用户注册!");
		return;
	}
	while(1)
	{
		//输入帐号
		bzero( sm , sizeof( struct msg ));
		puts("please enter your username:");
		scanf("%s",login.name);
		sm->type = MSG_DATA;
		sm->data_len = strlen(login.name);
		memcpy(sm->data,login.name,sm->data_len);
		//将帐号发送给服务器判断是否存在
		if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
			perror("send_add");
		len = recv( fd , (void *)rm , MAXSIZE , 0 );
		if( len < 0 )
			perror("add_recv_len2");
		if( rm->type == MSG_UNACK )
		{
			puts("该帐号已存在!");
			continue;
		}
		puts("该帐号可以使用!");
		while(1)
		{
			puts("please enter your passwd:");
			scanf("%s",login.passwd);
			puts("please enter your passwd again:");
			scanf("%s",mypasswd);
			if( strcmp(login.passwd,mypasswd) == 0 )
			{
				break;
			}
			else
				puts("两次密码不同,请重新输入!");
		}
		//将密码发送给服务器
		bzero( sm , sizeof( struct msg ));
		sm->type = MSG_DATA;
		sm->data_len = strlen(login.passwd);
		memcpy(sm->data,login.passwd,sm->data_len);
		if( send( fd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
			perror("send_add");
		len = recv( fd , (void *)rm , MAXSIZE , 0 );
		if( len < 0 )
			perror("add_recv_len2");
		if( rm->type == MSG_ACK )
		{
			//将邮箱发送给服务器
			puts("please enter your email:");
			scanf("%s",login.email);
			bzero( sm , sizeof( struct msg ));
			sm->type = MSG_DATA;
			sm->data_len = strlen(login.email);
			memcpy(sm->data,login.email,sm->data_len);
			if( send( fd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
				perror("send_add");
			len = recv( fd , (void *)rm , MAXSIZE , 0 );
			if( len < 0 )
				perror("add_recv_len2");
			if( rm->type == MSG_ACK )
			{
				puts("注册成功!");
				break;
			}
		}
	}
}
//更改密码函数
void chg_msg()
{
	getchar();
	//发送更改信号给服务器
	sm->type = MSG_CHANGE;
	sm->data_len = 0;
	if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
		perror("send_add");
	//接收来自服务器的回复
	len = recv( fd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	//服务器不允许更改
	if( rm->type == MSG_UNACK )
	{
		puts("目前不能进行密码更改!");
		return;
	}
	//输入帐号
	bzero( sm , sizeof( struct msg ));
	puts("please enter your username:");
	scanf("%s",login.name);
	sm->type = MSG_DATA;
	sm->data_len = strlen(login.name);
	memcpy(sm->data,login.name,sm->data_len);
	//将帐号发送给服务器判断是否存在
	if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
		perror("send_add");
	len = recv( fd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	if( rm->type == MSG_UNACK )
	{
		puts("该帐号不存在!");
		return;
	}
	//将邮箱发送给服务器
	puts("please enter your email:");
	scanf("%s",login.email);
	bzero( sm , sizeof( struct msg ));
	sm->type = MSG_DATA;
	sm->data_len = strlen(login.email);
	memcpy(sm->data,login.email,sm->data_len);
	if( send( fd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
		perror("send_add");
	len = recv( fd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	if( rm->type == MSG_UNACK )
	{
		puts("邮箱错误!");
		return;
	}
	//将新密码发送给服务器
	puts("please enter your newpasswd:");
	scanf("%s",login.passwd);
	bzero( sm , sizeof( struct msg ));
	sm->type = MSG_DATA;
	sm->data_len = strlen(login.passwd);
	memcpy(sm->data,login.passwd,sm->data_len);
	if( send( fd , (void *)sm , sizeof(struct msg) , 0 ) < 0 ) 
		perror("send_add");
	puts("修改成功!");
}
//私聊
void chat_private()
{
	usleep(100);
	char projectName[25] = {0};
	char content[100] = {0};
	if( forbidden_flag == 1 )
	{
		printf("您已被禁言!\n");
		return;
	}
	//输入对方用户名
	getchar();
	printf("请输入对方用户名:");
	scanf("%s",projectName);
	bzero( sm , sizeof( struct msg ));
	sm->type = MSG_DATA;
	sm->data_len = sizeof(projectName);
	memcpy( sm->data , projectName , sm->data_len);
	//将帐号发送给服务器判断是否存在
	if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
		perror("send_add");
	if( non_people == 1 )
	{
		puts("该用户不存在(或已离线)!");
		return;
	}
	printf("请输入要发送的内容:");
	getchar();
	fgets( content , sizeof(content) , stdin );
	bzero( sm , sizeof( struct msg ));
	sm->type = MSG_PRIVATE;
	sm->data_len = strlen(content);
	memcpy( sm->data , content , sm->data_len);
	//将内容发送给服务器
	if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
		perror("send_add");
	if( non_people == 1 )
	{
		puts("该用户不存在(或已离线)!");
		return;
	}
}
//群聊
void chat_group()
{
	usleep(100);
	char content[100] = {0};
	if( forbidden_flag == 1 )
	{
		printf("您已被禁言!\n");
		return;
	}
	printf("请输入要发送的内容:");
	getchar();
	fgets( content , sizeof(content) , stdin );
	bzero( sm , sizeof( struct msg ));
	sm->type = MSG_GROUP;
	sm->data_len = strlen(content);
	memcpy( sm->data , content , sm->data_len);
	//将内容发送给服务器,通过服务器发送给对方
	if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
		perror("send_add");
}
//文件传输
void file_transfer()
{
	char filename[100];
	FILE *fp;
	char buf[1024]={0};
	size_t fsize;
	usleep(100);
	if( forbidden_flag == 1 )
	{
		printf("您已被禁言!\n");
		return;
	}
	printf("请输入需要传输的文件名:");
	scanf("%s",filename);
	fp = fopen(filename,"r");
	if(fp == NULL)
	{
		perror("openfile");
		exit(1);
	}
	rewind(fp);
	bzero( sm , sizeof(struct msg));
	while((fsize = fread(sm->data,sizeof(char),sizeof(sm->data)-1,fp)))
	{
		
		sm->type = 4;
		sm->data_len = sizeof(sm->data)-1;
		if(send(fd,(void *)sm,sizeof(struct msg),0)<0)
			perror("send_add");
		if(fsize < sizeof(sm->data)-1)
			break;
		bzero( sm , sizeof(struct msg));
	}
	bzero( sm , sizeof(struct msg));
	fclose(fp);
}
//踢人
void kick_people()
{
	usleep(100);
	char kick_name[25]={0};
	if( master == 0 )
	{
		puts("您不是群主!");
		return;
	}
	else if( master == 1 )
	{
		getchar();
		printf("尊贵的群主,请输入你要踢的用户名称:");
		scanf("%s",kick_name);
		bzero( sm , sizeof( struct msg ));
		sm->type = MSG_DATA;
		sm->data_len = sizeof(kick_name);
		memcpy( sm->data , kick_name , sm->data_len);
		if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
			perror("send_add");
		if( non_people == 1 )
		{
			puts("该用户不存在!");
			return;
		}
		puts("成功踢出!");
	}
}
//禁言
void forbidden_people()
{
	usleep(100);
	char forbidden_name[25]={0};
	if( master == 0 )
	{
		puts("您不是群主!");
		return;
	}
	else if( master == 1 )
	{
		getchar();
		printf("尊贵的群主,请输入你要禁言的用户名称:");
		scanf("%s",forbidden_name);
		bzero( sm , sizeof( struct msg ));
		sm->type = MSG_DATA;
		sm->data_len = sizeof(forbidden_name);
		memcpy( sm->data , forbidden_name , sm->data_len);
		if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
			perror("send_add");
		if( non_people == 1 )
		{
			puts("该用户不存在!");
			return;
		}
		puts("成功禁言!");
	}
}
//解禁
void lift_a_ban()
{
	usleep(100);
	char lift_name[25]={0};
	if( master == 0 )
	{
		puts("您不是群主!");
		return;
	}
	else if( master == 1 )
	{
		getchar();
		printf("尊贵的群主,请输入你要解禁的用户名称:");
		scanf("%s",lift_name);
		bzero( sm , sizeof( struct msg ));
		sm->type = MSG_DATA;
		sm->data_len = sizeof(lift_name);
		memcpy( sm->data , lift_name , sm->data_len);
		if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
			perror("send_add");
		if( non_people == 1 )
		{
			puts("该用户不存在!");
			return;
		}
		puts("成功解禁!");
	}
}
//用户注销
void cancellation_user()
{
	//发送请求信号给服务器
	sm->type = 0;
	sm->data_len = 0;
	if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
		perror("send_add");
}
//接收函数
void *server_receive()
{
	while(1)
	{
		bzero( rm , sizeof( struct msg ));
		recv( fd , (void *)rm , MAXSIZE , 0 );
		if( rm->type == MSG_PRIVATE )//接受私聊消息
		{
			printf("\n");
			puts(rm->data);
		}
		else if( rm->type == MSG_GROUP ) //接收群发消息
		{
			printf("\n");
			puts(rm->data);
		}
		else if( rm->type == MSG_FILE )
		{
		}
		else if( rm->type == MSG_NUM ) //在线人数打印
		{
			printf("\n当前在线人数为:%s\n",rm->data);
		}
		else if( rm->type == MSG_KICK )
		{
			kick = 1;
			cancellation_user();//用户注销
			chat_flag = 1;
			printf("\n你已被踢出群聊!请按任意键继续\n");
			pthread_cancel(tid);
		}
		else if( rm->type == MSG_MASTER )
		{
			master = 1; //代表是群主
		}
		else if( rm->type == MSG_UNMASTER )
		{
			master = 0; //代表不是群主
		}
		else if( rm->type == MSG_FORBIDDEN )
		{
			forbidden_flag = 1; //被禁言
			lift_flag = 0; //没有被解禁
		}
		else if( rm->type == MSG_LIFT )
		{
			printf("您已被解除禁言!\n");
			forbidden_flag = 0; //被禁言
			lift_flag = 1; //被解禁
		}
		else if( rm->type == MSG_PEOPLE )
		{
			non_people = 0;
		}
		else if( rm->type == MSG_NONPEOPLE )
		{
			non_people = 1;
		}
	}
}
//聊天界面
void chat_menu() 
{
	int ret = 0;
	//创建子进程
	ret = pthread_create(&tid, NULL, server_receive, NULL);
    if(0 != ret)
        perror("pthread_create");
	while(start)
	{
		int choice;
		if( kick == 0)
		{
			puts(" ---------------------------------- ");
			puts(" ---------------------------------- ");
			puts(" -------   聊天群功能界面:   ------ ");
			puts(" ---------------------------------- ");
			puts(" ---------1:在线人数查询------------ ");
			puts(" ---------2:私聊-------------------- ");
			puts(" ---------3:群聊-------------------- ");
			puts(" ---------4:文件传输---------------- ");
			puts(" ---------5:踢人(限群主使用)------- ");
			puts(" ---------6:禁言(限群主使用)------- ");
			puts(" ---------7:解禁(限群主使用)------- ");
			puts(" ---------0:注销-------------------- ");
			puts(" ----------------------------------- ");
			puts(" ----------------------------------- ");
			printf("please choice one:");
			scanf("%d",&choice);
			switch(choice)
			{
				case 1:
						sm->type = 1; //在线人数查询
						sm->data_len = 0;
						if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
						perror("send_add");
						break;
				case 2:
						sm->type = 2;
						sm->data_len = 0;
						if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
						perror("send_add");
						chat_private(); //私聊
						break;
				case 3:
						sm->type = 3;
						sm->data_len = 0;
						if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
						perror("send_add");
						chat_group();//群聊
						break;
				case 4:
						bzero(sm,sizeof(struct msg));
						sm->type = 4;
						sm->data_len = 0;
						if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
						perror("send_add");
						file_transfer();//文件传输
						break;
				case 5:
						sm->type = 5;
						sm->data_len = 0;
						if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
						perror("send_add");
						kick_people();//踢人
						break;
				case 6:
						sm->type = 6;
						sm->data_len = 0;
						if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
						perror("send_add");
						forbidden_people();//禁言
						break;
				case 7:
						sm->type = 7;
						sm->data_len = 0;
						if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
						perror("send_add");
						lift_a_ban();//解禁
						break;
				case 0:
						cancellation_user();//用户注销
						pthread_cancel(tid);
						chat_flag = 1;
						break;
				default:
						puts(" ---  enter right choice  --- ");
						continue;
			}
			if( chat_flag == 1 )
			{
				break;
			}
		}
		else
		{
			getchar();
			break;
		}
	}	
}
//用户登录函数
void login_msg()
{
	getchar();
	//发送登录信号给服务器
	sm->type = MSG_LOGIN;
	sm->data_len = 0;
	if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
		perror("send_add");
	//接收来自服务器的回复
	len = recv( fd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	//服务器不允许登录
	if( rm->type == MSG_UNACK )
	{
		puts("目前不能进行用户登录!");
		return;
	}
	//输入帐号
	bzero( sm , sizeof( struct msg ));
	puts("please enter your username:");
	scanf("%s",login.name);
	sm->type = MSG_DATA;
	sm->data_len = strlen(login.name);
	memcpy(sm->data,login.name,sm->data_len);
	//将帐号发送给服务器判断是否存在
	if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
		perror("send_add");
	len = recv( fd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	if( rm->type == MSG_UNACK )
	{
		puts("该帐号不存在!");
		return;
	}
	//输入密码
	bzero( sm , sizeof( struct msg ));
	puts("please enter your passwd:");
	scanf("%s",login.passwd);
	sm->type = MSG_DATA;
	sm->data_len = strlen(login.passwd);
	memcpy(sm->data,login.passwd,sm->data_len);
	//将密码发送给服务器判断是否正确
	if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
		perror("send_add");
	len = recv( fd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	if( rm->type == MSG_UNACK )
	{
		puts("密码错误!");
		return;
	}
	//发送登录信号,查看是否已经在线
	sm->type = MSG_LOGIN;
	sm->data_len = 0;
	if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
		perror("send_add");
	//接收来自服务器的回复
	len = recv( fd , (void *)rm , MAXSIZE , 0 );
	if( len < 0 )
		perror("add_recv_len2");
	//用户已经在线
	if( rm->type == MSG_UNACK )
	{
		puts("用户登录已达上限!");
		return;
	}
	//调用聊天菜单
	chat_menu();
}
//用户退出函数
void logout_msg()
{
	//发送退出信号给服务器
	sm->type = MSG_LOGOUT;
	sm->data_len = 0;
	if( send( fd , (void *)sm , MAXSIZE , 0 ) < 0 ) 
		perror("send_add");
	puts("成功退出!");
}
//菜单
void cli_menu()
{
	int menu_flag = 0;
	while(start)
	{
		int choice;
		puts(" ----------------------- ");
		puts(" ----------------------- ");
		puts(" ---      choice:   --- ");
		puts(" -------1:用户注册------- ");
		puts(" -------2:更改密码------- ");
		puts(" -------3:用户登录------- ");
		puts(" -------4:用户退出------- ");
		puts(" ----------------------- ");
		puts(" ----------------------- ");
		printf("please choice one:");
		scanf("%d",&choice);
		switch(choice)
		{
			case 1:
						add_msg(); //用户注册
						break;
			case 2:
						chg_msg(); //更改密码
						break;
			case 3:
						login_msg();//用户登录
						break;
			case 4:
						logout_msg();//用户退出
						menu_flag = 1;
						close_cli();
						break;
			default:
						puts(" ---  enter right choice  --- ");
						continue;
		}
		if( menu_flag == 1 )
		{
			break;
		}
	}
}
int main()
{
	signal(SIGINT,sigfun);
	init_cli();
	cli_menu();
	return 0;
}

脚本文件:
bash.sh

gcc client.c -o client -lpthread
gcc server.c -o server -lpthread -L /mysql/include -lmysqlclient

不用脚本直接在终端输入上面两行命令也行,但注意mysql.h的文件路径在哪,我的是在/mysql/include下,所以-L后面加上路径,如果你们的路径不再该目录下,就把在你Ubuntu下mysql.h的路径写在后面即可。如果电脑中没有生成过这个头文件,比如我刚用数据库的时候。

test.c:4:19: fatal error: mysql.h: 没有那个文件或目录
 #include "mysql.h"
                   ^
compilation terminated.

会遇到上面这个错误
解决方法:sudo apt-get install libmysqlclient15-dev安装此软件包
然后在/usr/include/mysql里可以找到mysql.h
编译的时候 gcc xx.c -o xx -L /usr/include/mysql -l mysqlclien
xx代表文件名

你可能感兴趣的:(testProject)