热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

聊天室(c/s架构)

项目要求:(1)采用ClientServer架构。(2)ClientA登陆聊天服务器前,需要注册自己的ID和密码。(3)注册成功后,ClientA就可以通
项目要求:

(1)采用 Client/Server 架构 。 

(2) Client A 登陆聊天服务器前,需要注册自己的 ID 和密码。 

(3)注册成功后,ClientA 就可以通过自己的 ID 和密码登陆聊天服务器 。 

(4). 多个 Client X 可以同时登陆聊天服务器之后,与其他用户进行通讯聊天。 

(5).Client A 成功登陆后可以查看当前聊天室内其他在线用户 Client x。 

(6). Client A 可以选择发消息给某个特定的 Client X,即”悄悄话”功能。

(7). Client A 可以选择发消息全部的在线用户,即”群发消息”功能。 

(8). Client A 在退出时需要保存聊天记录。 

(9). Server 端维护一个所有登陆用户的聊天会的记录文件,以便备查。

1、服务器

#include 
#include
#include
#include
#include
#include
#include
#include
#include

#define PORT 9999

struct User //用户信息结构体
{
char name[20]; //储存用户名
char password[20]; //储存密码
char signature[50]; //储存个性签名
int socket; //储存套接字
int cmd; // 消息类型
char msg[1024]; // 消息内容
char toname[20];
char fromname[20];
char logout;
char file_name[20];
char file_msg[1024];
};

struct User user[5];

sqlite3 * database;

sqlite3 * server_sqlite() //数据库函数
{
sqlite3 * database;

// 打开数据库
int ret = sqlite3_open("usermes.db", &database);
if (ret != SQLITE_OK)
{
printf ("错误代码\n");
perror("sqlite3_open");
return NULL;
}

char *errmsg = NULL;
char *sql = "create table if not exists usermes(name TEXT, password TEXT, signature TEXT, primary key(name))";
ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
return NULL;
}
return database;
}

int init_socket() //套接字初始化
{
int listen_socket = socket (AF_INET, SOCK_STREAM, 0);
if(listen_socket == -1)
{
printf("错误代码55\n");
perror("socket");
return -1;
}

struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET; // 设置地址族
addr.sin_port = htons(PORT); // 设置本地端口
addr.sin_addr.s_addr = htonl(INADDR_ANY); // 使用本地的任意IP地址

int ret = bind(listen_socket, (struct sockaddr *)&addr, sizeof(addr)); //绑定套接字
if (ret == -1)
{
printf("错误代码69\n");
perror ("bind");
return -1;
}

// 3、监听本地套接字
ret = listen(listen_socket, 5);
if (ret == -1)
{
printf("错误代码78\n");
perror ("listen");
return -1;
}

printf("等待客户连接。。。。\n");
return listen_socket;
}

int MyAccept(int listen_socket) //连接客户端
{
struct sockaddr_in client_addr; // 用来保存客户端的ip和端口信息
int len = sizeof(client_addr);
int client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, &len);
if (client_socket == -1)
{
printf("错误代码93\n");
perror ("accept");
}

printf ("成功接收一个客户端: %s\n", inet_ntoa(client_addr.sin_addr));

return client_socket;
}

void reg(int client_socket, struct User *buf) //注册
{
char str[1024];
sqlite3 * database;
int i;
database = server_sqlite(); //打开数据库
char *errmsg = NULL;
sprintf (str, "insert into usermes values('%s', '%s', '666')", buf->name, buf->password);
int ret = sqlite3_exec(database, str, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
buf->cmd = -2;
write(client_socket, buf, sizeof(struct User));
}
else
{
printf("注册成功\n");
buf->cmd = 1000;
write(client_socket, buf, sizeof(struct User));
}
sqlite3_close(database); // 关闭数据库
}

void log_in(int client_socket, struct User *buf) //登录
{
sqlite3 * database = server_sqlite();
char *errmsg = NULL;
char **resultp = NULL;
int nrow, ncolumn;
char *sql = "select * from usermes";
int ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
return;
}
printf("正在匹配账户和密码....\n");
int i;
int k;
for (i = 3; i <(nrow+1)*ncolumn; i++)
{
if(strncmp(resultp[i], buf->name, strlen(buf->name)) == 0)
{
if(strncmp(resultp[i+1], buf->password, strlen(buf->password)) == 0)
{
for(k = 0; k <5; k++)
{
if(user[k].socket == 0)
{
strcpy (user[k].name , buf->name);
user[k].socket = client_socket;
buf->cmd = 1001;
strcpy(buf->signature,resultp[i+2]);
write(client_socket, buf, sizeof(struct User));
printf("密码账号匹配成功\n");
break;
}
}
if(k == 5)
{
printf("在线人数已达上限\n");
buf->cmd = -3;
write(client_socket, buf, sizeof(struct User));
}
return;
}
printf("账户和密码匹配不成功\n");
buf->cmd = -4;
write(client_socket, buf, sizeof(struct User));
break;
}
}
if(i = (nrow+1)*ncolumn)
{
printf("没有此用户\n");
buf->cmd = -4;
write(client_socket, buf, sizeof(struct User));
}
sqlite3_free_table(resultp);
sqlite3_close(database);
}

void View_profile(int client_socket, struct User *buf) //查看在线好友
{
printf("%s 要查看在线好友\n", buf->name);
buf->cmd = 1002;
int i;
for(i = 0; i <5; i++)
{
if(user[i].socket != 0)
{
strcpy(buf->msg,user[i].name);
write(client_socket, buf, sizeof(struct User));
}
}
}

void Modify_the_signature(int client_socket, struct User *buf) //修改个签
{
sqlite3 * database = server_sqlite();
printf("%s 要修改个性签名\n", buf->name);
char *errmsg = NULL;
char sql[1024] ;
sprintf(sql, "update usermes set signature = '%s'where name = '%s'", buf->signature, buf->name);
int ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
buf->cmd = -1;
printf ("数据库操作失败:%s\n", errmsg);
sqlite3_close(database);
return;
}
buf->cmd = 1003;
write(client_socket, buf, sizeof(buf));
printf("个性签名修改成功\n");

sqlite3_close(database);
}

void Private_chat(int client_socket, struct User *buf) //私聊
{
sqlite3 * database = server_sqlite();
printf("%s 要进行私聊\n", buf->name);
int i;
char *errmsg = NULL;
char **resultp = NULL;
int nrow, ncolumn;
char *sql = "select name from usermes";
int ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
return;
}
for (i = 1; i <(nrow+1)*ncolumn; i++)
{
if(strncmp(resultp[i], buf->toname, strlen(buf->toname)) == 0)
{
break;
}
}
if(i == (nrow+1)*ncolumn)
{
buf->cmd = -3; //服务器不存在该用户
write(client_socket, buf, sizeof(struct User));
sqlite3_close(database);
return;
}

for(i = 0; i <5; i++)
{
if(strncmp(user[i].name, buf->toname, strlen(buf->toname)) == 0)
{
buf->cmd = 1004;
write(user[i].socket, buf, sizeof(struct User));
break;
}
}

if(i == 5)
{
buf->cmd = -2; //要发送消息的人不在线
write(client_socket, buf, sizeof(struct User));
}

sqlite3_close(database);
}

void Group_chat(int client_socket, struct User *buf) //群聊
{
printf("%s 要进行群聊\n", buf->name);
buf->cmd = 1005;
int i;
for(i = 0; i <5; i++)
{
if(user[i].socket != 0)
{
write(user[i].socket, buf, sizeof(struct User));
}
}
}

void Logout(int client_socket, struct User *buf) //注销函数
{
printf("%s 要注销此用户\n", buf->name);
sqlite3 * database = server_sqlite();
int i;
char *errmsg = NULL;
char **resultp = NULL;
int nrow, ncolumn;
char sql[1024];
sprintf(sql,"delete from usermes where name = '%s'", buf->name);
int ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
return;
}
buf->cmd = 1006;
printf("此用户已经成功注销\n");
write(client_socket, buf, sizeof(struct User));
sqlite3_close(database);
}

void Send_file(int client_socket, struct User *buf) //文件传输函数
{
sqlite3 * database = server_sqlite();
printf("%s 要向 %s 发送文件\n", buf->name, buf->toname);

int i;
for(i = 0;i <5; i++)
{
if(strncmp(user[i].name, buf->toname, strlen(buf->toname)) == 0)
{
strcpy(buf->file_name, buf->name);
buf->cmd = 1007;
write(user[i].socket, buf, sizeof(struct User));
printf("文件发送中。。。\n");
break;
}
}
}

void exit_chat(int client_socket, struct User *buf) //退出聊天室
{
printf("%s 要退出聊天室\n", buf->name);

int i;
for(i = 0; i <5; i++)
{
if(strcmp(user[i].name, buf->name) == 0)
{
memset(&user[i], 0, sizeof(struct User));
printf("聊天室退出成功\n");
buf->cmd = 1008;
write(client_socket, buf, sizeof(struct User));
break;
}
}
}

void exchang_password(int client_socket, struct User *buf) //修改密码
{
printf("%s 要修改密码\n", buf->name);
sqlite3 * database;
int i;
char str[1024];
database = server_sqlite(); //打开数据库
char *errmsg = NULL;
sprintf (str, "update usermes set password = '%s'where name = '%s'", buf->password, buf->name);
int ret = sqlite3_exec(database, str, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
buf->cmd = -4;
write(client_socket, buf, sizeof(struct User));
}
else
{
printf("密码修改成功\n");
buf->cmd = 1009;
write(client_socket, buf, sizeof(struct User));
}
sqlite3_close(database); // 关闭数据库
}

void *hanld_client(void *v)
{
int client_socket = (int)v;
struct User buf;

while(1)
{
// 从客户端读一个结构体数据
int ret = read(client_socket, &buf, sizeof(buf));
if (ret == -1)
{
printf("错误代码\n");
perror ("read");
break;
}

if(ret == 0)
{
printf("客户端退出\n");
break;
}

switch (buf.cmd)
{
case 1 : // 客户端进行注册
printf("客户进行注册\n");
reg(client_socket, &buf);
break;
case 2 : // 客户端进行登录
log_in(client_socket, &buf);
break;
case 3 : // 客户端退出
printf("客户端退出\n");
break;
case 4: //查看在线好友
View_profile(client_socket, &buf);
memset(&buf, 0, sizeof(buf));
break;
case 5: //修改个性签名
Modify_the_signature(client_socket, &buf);
break;
case 6: //私聊
Private_chat(client_socket, &buf);
break;
case 7: //群聊
Group_chat(client_socket, &buf);
break;
case 8: //注销此用户
Logout(client_socket, &buf);
break;
case 9: //发送文件
Send_file(client_socket, &buf);
break;
case 10: //退出聊天室
exit_chat(client_socket, &buf);
break ;
case 11: //修改密码
exchang_password(client_socket, &buf);
break;
default:
printf("输入有误,请重新输入\n");
break;
}
}
}

int main()
{
int listen_socket = init_socket(); //初始化监听套接字

while (1)
{
// 获取与客户端连接的套接字
int client_socket = MyAccept(listen_socket);

// 创建一个线程去处理客户端的请求,主线程依然负责监听
pthread_t id;
pthread_create(&id, NULL, hanld_client, (void *)client_socket);

pthread_detach(id); // 线程分离
}

close (listen_socket);

return 0;
}

2、客户端

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define PORT 9999

struct User //用户信息结构体
{
char name[20]; //储存用户名
char password[20]; //储存密码
char signature[50]; //储存个性签名
int socket; //储存套接字
int cmd; // 消息类型
char msg[1024]; // 消息内容
char toname[20];
char fromname[20];
char logout[2];
char file_name[20];
char file_msg[1024];
};

int init_socket()
{
int client_socket = socket (AF_INET, SOCK_STREAM, 0);
if(client_socket == -1)
{
printf("\t\t错误代码\n");
perror("socket");
return -1;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET; // 设置地址族
addr.sin_port = htons(PORT); // 设置本地端口
inet_aton("127.0.0.1",&(addr.sin_addr));


// 连接服务器,如果成功,返回0,如果失败,返回-1
// 成功的情况下,可以通过socketfd与服务器进行通信
int ret = connect(client_socket, (struct sockaddr *)&addr, sizeof(addr));
if (ret == -1)
{
perror ("connect");
return -1;
}
return client_socket;
}

void Home_interface() //主界面
{
system("clear");
printf("\n\n\n\n");
printf("\t\t请输入对应功能的号码\n");
printf("\t\t\t1、注册\n");
printf("\t\t\t2、登录\n");
printf("\t\t\t3、退出\n");
}

sqlite3 * chat_sqlite() //聊天数据库,保存聊天记录
{
sqlite3 * database;

// 打开数据库
int ret = sqlite3_open("chathistory.db", &database);
if (ret != SQLITE_OK)
{
printf ("错误代码\n");
perror("sqlite3_open");
return NULL;
}

char *errmsg = NULL;
char *sql = "create table if not exists chathistory(fromname TEXT, toname TEXT, msg TEXT)";
ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
return NULL;
}
return database;
}

void func_interface(struct User *user) //功能界面
{
system("clear");
printf("☺:%s\n", user->signature);
printf("\n\n");
printf("\t\t请输入对应功能的号码\n");
printf("\t\t\t1、查看在线好友\n");
printf("\t\t\t2、修改个性签名\n");
printf("\t\t\t3、私聊\n");
printf("\t\t\t4、群聊\n");
printf("\t\t\t5、注销此用户\n");
printf("\t\t\t6、发送文件\n");
printf("\t\t\t7、查看聊天记录\n");
printf("\t\t\t8、退出聊天室\n");
printf("\t\t\t9、修改密码\n");

}

void reg(int client_socket) //注册函数
{
struct User user;
user.cmd = 1;
//printf("\n\n\n\n");
printf("\t\t请输入用户名:");
scanf("%s", user.name);
printf("\t\t请输入密码:");
scanf("%s", user.password);

write(client_socket, &user, sizeof(user));

read(client_socket, &user, sizeof(user));
if(user.cmd == -2)
{
printf("\t\t已有用户,请重新注册\n");
}
if(user.cmd == 1000)
{
printf("\t\t注册成功\n");
}
else
{
printf("\t\t注册失败,请重新注册\n");
sleep(1);
}
}

void View_profile(int client_socket,struct User *user) //查看在线好友
{
user->cmd = 4;
write(client_socket, user, sizeof(struct User));

printf("\t\t请按回车键返回主界面\n");
getchar();
getchar();
}

void Modify_the_signature(int client_socket,struct User *user) //修改个签
{
user->cmd = 5;
printf("\t\t请输入你想输入的个性签名:\n");
scanf("%s", user->signature);
write(client_socket, user, sizeof(struct User));
}

void Private_chat(int client_socket,struct User *user) //私聊
{
sqlite3 * database = chat_sqlite();

user->cmd = 6;
printf("\t\t请输入你想聊天的对象:");
scanf("%s", user->toname);
strcpy(user->fromname, user->name);
printf("\t\t请输入聊天内容:");
scanf("%s", user->msg);
write(client_socket, user, sizeof(struct User));

char *errmsg = NULL;
char str[1024];
sprintf (str, "insert into chathistory values('%s', '%s', '%s')",user->fromname, user->toname, user->msg);
int ret = sqlite3_exec(database, str, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
perror("sqlite3_exec");
}

sqlite3_close(database);
}

void Group_chat(int client_socket,struct User *user)
{
sqlite3 * database = chat_sqlite();
user->cmd = 7;
printf("请输入聊天内容:");
scanf("%s", user->msg);
write(client_socket, user, sizeof(struct User));

char *errmsg = NULL;
char str[1024];
sprintf (str, "insert into chathistory values('%s', 'everyone', '%s')",user->name, user->msg);
int ret = sqlite3_exec(database, str, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
perror("sqlite3_exec");
}

sqlite3_close(database);
}

void * readMsg(void *v) //读写分离
{
sqlite3 * database = chat_sqlite();
int client_socket = (int)v;
struct User buf;
char str[1024];
int ret;
char *errmsg = NULL;
char file_name[20];
while (1)
{
int ret = read (client_socket, &buf, sizeof(buf));
if(ret == -1)
{
perror("read");
break;
}
switch (buf.cmd)
{
case 1002: //查看好友
system("clear");
printf("\n\n\n\n");
printf("\t\t在线的人有:%s\n", buf.msg);
break;
case 1003: //修改个签
printf("个性签名修改成功\n");
sleep(1);
break;
case -1:
printf("个性签名修改失败\n");
sleep(1);
break;
case 1004: // 私聊
printf("\n");
printf ("%s 给你发一条消息:%s\n", buf.fromname, buf.msg);
sprintf (str, "insert into chathistory values('%s', '%s', '%s')",buf.fromname, buf.toname, buf.msg);
ret = sqlite3_exec(database, str, NULL, NULL, &errmsg);
break;
case -2:
printf("该对象不在线\n");
break;
case -3:
printf("不存在该对象\n");
break;
case 1005: // 群聊
printf("\n");
printf ("收到一条群消息: %s\n", buf.msg);
sprintf (str, "insert into chathistory values('%s', 'everyone', '%s')",buf.name, buf.msg);
ret = sqlite3_exec(database, str, NULL, NULL, &errmsg);
break;
case 1006: //注销
printf("注销成功\n");
sleep(1);
sqlite3_close(database);
return ;
case 1008:
printf("成功退出聊天室\n");
sleep(1);
sqlite3_close(database);
return;
case 1009:
printf("密码修改成功\n");
sleep(1);
break;
case -4:
printf("密码修改失败\n");
sleep(1);
break;
case 1007:
printf("\n");
printf("%s 要给你传输文件\n", buf.name);

ret = open("text", O_WRONLY | O_CREAT, 0777);
if(ret == -1)
{
perror ("open ret");
break;
}
write(ret, buf.file_msg, strlen(buf.file_msg));
close(ret);
printf("成功接收到文件!\n");
break;
}

}
}

int Logout(int client_socket,struct User *user)
{
char buf[] = "y";
printf("是否注销此用户,请输入y/n \n");
scanf("%s", user->logout);

if(strcmp(user->logout, buf) == 0)
{
user->cmd = 8;
write(client_socket, user, sizeof(struct User));
printf("正在注销。。。\n");
sleep(1);
return 1;
}
else
{
return 0;
}
}

void Send_file(int client_socket,struct User *user) //发送文件
{
user->cmd = 9;
printf("请输入要发送文件的对象:");
scanf("%s", user->toname);
printf("请选择要发送的文件:");
scanf("%s", user->file_name);
int fd = open(user->file_name, O_RDWR);
if(fd == -1)
{
printf("文件打开失败\n");
perror("open");
return;
}
printf("文件正在发送\n");
int ret;

while(ret = read(fd, user->file_msg, 1024))
{
if(ret == -1)
{
printf("文件读取失败\n");
perror("read");
return;
}
write(client_socket, user, sizeof(struct User));
usleep(5);
}
printf("文件发送成功\n");
close(fd);
}

void chat_history() //查看聊天记录函数
{
sqlite3 * database = chat_sqlite();
char *errmsg = NULL;
char **resultp = NULL;
int nrow, ncolumn;
char *sql = "select * from chathistory";
int ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);
if (ret != SQLITE_OK)
{
printf ("数据库操作失败:%s\n", errmsg);
return;
}
int i;
for(i = 0; i <(nrow+1)*ncolumn; i++)
{
if (i % ncolumn == 0)
printf ("\n");
printf("%-16s", resultp[i]);
}
printf("\n");
printf("请按回车键返回主界面\n");
getchar();
getchar();

sqlite3_close(database);
}

void exit_chat(int client_socket,struct User *user)
{
user->cmd = 10;
write(client_socket, user, sizeof(struct User));
printf("正在退出....\n");
sleep(1);
}

void exchang_password(int client_socket,struct User *user)
{
user->cmd = 11;
printf("请输入要修改的密码:");
scanf("%s", user->password);
write(client_socket, user, sizeof(struct User));

printf("正在修改密码\n");
sleep(1);
}

void log_in(int client_socket)
{
struct User user;
user.cmd = 2;

while(1)
{
printf("\n\n\n\n");
printf("\t\t请输入用户名:");
scanf("%s", user.name);
printf("\t\t请输入密码:");
scanf("%s", user.password);

write(client_socket, &user, sizeof(user));

read(client_socket, &user, sizeof(user));
if(user.cmd == -3)
{
printf("\t\t客户已达上限,请稍后登录\n");
return;
}
if(user.cmd == -4)
{
printf("\t\t密码或用户名不对,请重新输入\n");
return;
}
if(user.cmd == 1001)
{
printf("\t\t正在登录。。。。。。\n");
//sleep(2);
printf("\t\t登录成功\n");
//sleep(1);

pthread_t id;
pthread_create(&id, NULL, readMsg, (void *)client_socket);
pthread_detach(id); // 读写分离

int ret;
int i;
while(1)
{
func_interface(&user); // 功能界面函数
printf("\t\t请输入对应功能的号码:");
scanf("%d",&i);
switch(i)
{
case 1:
View_profile(client_socket, &user); //查看在线好友
break;
case 2:
Modify_the_signature(client_socket, &user); //修改个性签名
break;
case 3:
Private_chat(client_socket, &user); //私聊
break;
case 4:
Group_chat(client_socket, &user); //群聊
break;
case 5:
ret = Logout(client_socket, &user); //注销此用户
if(ret == 1)
return;
break;
case 6:
Send_file(client_socket, &user); //发送文件
break;
case 7:
chat_history(); //查看聊天记录
break;
case 8: //退出聊天室
exit_chat(client_socket, &user);
return;
case 9: //修改密码
exchang_password(client_socket, &user);
break ;
default:
printf("\t\t输入有误,请重新输入\n");
break;
}
}
}
}
}

int main()
{
int client_socket = init_socket (); //客户端初始化套接字
while(1)
{
struct User user;
Home_interface();
printf("\t\t请输入对于功能的号码:");
scanf("%d", &user.cmd);
printf("\n");
switch(user.cmd)
{
case 1:
reg(client_socket); //注册函数
break;
case 2:
log_in(client_socket); //登录函数
break;
case 3:
write(client_socket, &user, sizeof(user));
exit(0);
break;
default:
printf("\t\t输入有误,请重新输入\n");
break;
}
}
return 0;
}



推荐阅读
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了在Win10上安装WinPythonHadoop的详细步骤,包括安装Python环境、安装JDK8、安装pyspark、安装Hadoop和Spark、设置环境变量、下载winutils.exe等。同时提醒注意Hadoop版本与pyspark版本的一致性,并建议重启电脑以确保安装成功。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • phpcomposer 那个中文镜像是不是凉了 ... [详细]
  • 本文主要复习了数据库的一些知识点,包括环境变量设置、表之间的引用关系等。同时介绍了一些常用的数据库命令及其使用方法,如创建数据库、查看已存在的数据库、切换数据库、创建表等操作。通过本文的学习,可以加深对数据库的理解和应用能力。 ... [详细]
  • MySQL语句大全:创建、授权、查询、修改等【MySQL】的使用方法详解
    本文详细介绍了MySQL语句的使用方法,包括创建用户、授权、查询、修改等操作。通过连接MySQL数据库,可以使用命令创建用户,并指定该用户在哪个主机上可以登录。同时,还可以设置用户的登录密码。通过本文,您可以全面了解MySQL语句的使用方法。 ... [详细]
author-avatar
伸手以后
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有