功能描述:1:开户;2:销户;3:存钱;4:取钱;5:查询;6:转账;
主要用的技术:
一:消息队列:
1)key_t key = ftok(".",100); //获取key
2)msgid = msgget(key,IPC_CREATE|0666); //创建 msgid = msgget(key,0); //获取
3)msgsnd = msgsnd = (msgid,&msg,sizeof(msg),0); //发送
4)msgrcv = msgrcv = (msgid,&msg,sizeof(msg),0,0); //获取
5)msgt = msgctl(msgid,IPC_RMID,NULL); //删除
二:信号:
signal(int sinno, void (*fa)(int));
三:文件操作:
int access(const char *filename); //查看文件是否存在
int open(int fd,int oflag,.../* mode_t mode*/)
ssize_t write(int fd,void *buf,size_t nbytes);
ssize_t read(int fd,void *buf,size_t nbytes);
思想架构:
头文件:
dao.h ----> 定义文件操作的函数
bank.h -----> 定义宏,结构体,设置外部变量 key1 key2
.c文件
client.c ----> 客户端操作 主要包括客户端的输入提示,和把数据传入服务器端
server.c ----> 创建消息队列,启动服务端,用vfork()创建子进程,用execl() 执行open.c 的目标文件。并且设定 SIG_INT 信号,接收此信号时就删除消息队列。
open.c -----> 用来接收客户端传来的消息,并对消息进行业务逻辑操作
dao.c -----> dao.h中一定的函数的具体实现,供open.c 文件调用,主要是用来对文件的操作。
bank.c ----> 此文件主要用来对两个 key 赋值。
感觉有点类似网站建设中的三层架构。
client.c 主要用来负责用户层
open.c 主要用来负责业务逻辑层
dao.c 主要用来负责数据操作层
设计的技术点不多,但是确实个规范的项目。头文件和各个文件的作用值得学习。框架是老师建的,功能都是自己实现的,如有错误还望指正:
bank.h:
//客户端和服务器端共用的头文件
#ifndef BANK_H_
#define BANK_H_
//声明两个key值,用来给消息队列用,这两个key在另一个文件中定义 extern const int key1;//客户端向服务器发送消息队列的键值key
extern const int key2;//服务器向客户端发送的 //消息类型 定义为各种宏 方便处理
#define M_OPEN 1//代表开户类型
#define M_DESTROY 2 //销户
#define M_SAVE 3 //存钱
#define M_TAKE 4 //取钱
#define M_QUERY 5 //查询
#define M_TRANSF 6 //转账
#define M_SUCCESS 7 //处理成功
#define M_FAILED 8 //处理失败 //包含帐户信息的帐户结构体
struct Account{
int id;//帐号
char name[];//用户名
char password[];//密码
double balance;//金额
}; //消息的结构体
struct Msg{
long mtype;//消息的类型
struct Account acc;//帐户的信息结构体
};
#endif
dao.h:
//数据对象的存储
#ifndef DAO_H_
#define DAO_H_
#include "bank.h"
//生成不重复的帐号
int generator_id();
//将新帐号添加到文件中,为开户服务
int createUser(struct Account acc);
//销户功能
int destroyUser(struct Account acc);
//存钱功能
int saveMoney(struct Account acc,struct Account *p);
//取钱功能
int getMoney(struct Account acc,struct Account *p);
//查询余额功能
int checkMoney(struct Account acc,struct Account *p);
//转账功能
int moveMoney(struct Account acc1,struct Account acc2,struct Account *p);
#endif
bank.c:
//对头文件中的变量进行定义
#include "bank.h" const int key1 = 0x12345678;
const int key2 = 0x23456789;
server.c:
//ATM的服务器端
#include "bank.h"
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h> //首先需要创建两个全局存储消息队列的id的变量
static int msgid1;
static int msgid2;
//写一个函数,用来创建两个消息队列,用到msgget函数
void init(){
//msgget函数,第一个参数是键值,bank.h中有
//IPC_CREAT表示没有此消息队列则创建,
//IPC_EXCL表示如果队列存在,则提示错误
//0666是给此消息队列对象添加一些权限设置,类似文件系统
//创建消息队列1
msgid1 = msgget(key1,IPC_CREAT|IPC_EXCL|);
if(msgid1 == -){
perror("消息队列1创建失败"),exit(-);
}
printf("消息队列1创建成功\n");
//创建消息队列2
msgid2 = msgget(key2,IPC_CREAT|IPC_EXCL|);
if(msgid2 == -){
perror("消息队列2创建失败");
exit(-);
}
printf("消息队列2创建成功\n");
}
//启动服务函数,用来创建子进程来执行用户不同的选择的结果
void start(){
printf("服务器正在启动..\n");
sleep();
//创建子进程
pid_t open_pid = vfork();
if(open_pid == -){
perror("vfork failed");
exit(-);
}
else if(open_pid == ){//进入子进程
//printf("in child process\n");
execl("./open","open",NULL);//不再和父进程共用代码段
exit(-);
}
else{
printf("正在等待客户端选择..\n");
waitpid(open_pid,,);//阻塞,等待子进程结束
//printf("in parent process\n");
}
} void sig_exit(){
printf("服务器正在关闭..\n");
sleep();
if(msgctl(msgid1,IPC_RMID,NULL) == -){
perror("消息队列1删除失败\n");
exit(-);
}
else{
printf("消息队列1删除成功\n");
}
if(msgctl(msgid2,IPC_RMID,NULL) == -){
perror("消息队列2删除失败\n");
exit(-);
}
else{
printf("消息队列2删除成功\n");
}
printf("服务器成功关闭\n");
exit();//直接结束程序 }
int main(){
//我们退出服务器用一个信号处理函数来实现
printf("退出服务器请按CTRL+C\n");//发送SIGINT信号
signal(SIGINT,sig_exit);//自定义信号处理函数,进行退出操作
//做好了善后工作,我们从头开始启动服务器
//创建消息队列
init();
//启动服务 start();
return ;
}
open.c:
/*开户*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "bank.h"
int main(){
int msgid1 = msgget(key1,);
if(msgid1 == -){
perror("获取消息队列1失败");
printf("服务器启动失败");
exit(-);
}
int msgid2 = msgget(key2,);
if(msgid2 == -){
perror("获取消息队列2失败");
printf("服务器启动失败");
exit(-);
}
//获取到消息队列之后,开始接受消息
while(){
struct Msg msg;//存储消息信息的结构体
struct Account accMove,accResult;//存储帐户信息
//首先从客户那里收取消息队列1的信息 msgrcv 函数
if(msgrcv(msgid1,&msg,sizeof(msg.acc),,) <= ){
break;
}
//如果接受到了消息,根据消息的不同类型进行不同的操作
if(msg.mtype == M_OPEN){//如果类型是开户
int id = generator_id();
accMove = msg.acc;
accMove.id = id;
if(createUser(accMove)==-){
printf("开户失败");
msg.mtype = M_FAILED;//将消息类型置成失败
}
else{
printf("开户成功");
msg.mtype = M_SUCCESS;
}
msg.acc.id = id;
msgsnd(msgid2,&msg,sizeof(msg.acc),);//将消息由消息队列2发送给客户端
//执行开户的操作
//给用户分配帐号,将用户信息记录在文件中。
}
//最后把消息发过去,这时候消息的类型应该是两种情况M_SUCESS
//或者是M_FAILED
else if(msg.mtype == M_DESTROY){
accMove = msg.acc;
int desval = destroyUser(accMove);
if(desval == -){
printf("没有此ID\n");
msg.mtype = M_FAILED;
}
else if(desval == ){
printf("销户失败!\n");
msg.mtype = M_FAILED;
}
else{
printf("销户成功!\n");
msg.mtype = M_SUCCESS;
}
if(msgsnd(msgid2,&msg,sizeof(msg.acc),) == -) perror("msgsnd"),exit(-);
}
else if(msg.mtype == M_SAVE){
accMove = msg.acc;
int saval = saveMoney(accMove,&accResult);
if(saval == -){
printf("没有此ID\n");
msg.mtype = M_FAILED;
}
else if(saval == ){
printf("存钱失败!\n");
msg.mtype = M_FAILED;
}
else{
printf("存钱成功!\n");
msg.mtype = M_SUCCESS;
}
msg.acc = accResult;
if(msgsnd(msgid2,&msg,sizeof(msg.acc),) == -) perror("msgsnd"),exit(-);
}
else if(msg.mtype == M_TAKE){
accMove = msg.acc;
int saval = getMoney(accMove,&accResult);
if(saval == -){
printf("没有此ID\n");
msg.mtype = M_FAILED;
}
else if(saval == ){
printf("余额不足\n");
msg.mtype = M_FAILED;
}
else if(saval == ){
printf("取钱失败!\n");
msg.mtype = M_FAILED;
}
else{
printf("取钱成功!\n");
msg.mtype = M_SUCCESS;
}
msg.acc = accResult;
if(msgsnd(msgid2,&msg,sizeof(msg.acc),) == -) perror("msgsnd"),exit(-); }
else if(msg.mtype == M_QUERY){
accMove = msg.acc;
int saval = checkMoney(accMove,&accResult);
if(saval == -){
printf("没有此ID\n");
msg.mtype = M_FAILED;
}
else if(saval == ){
printf("查询失败!\n");
msg.mtype = M_FAILED;
}
else{
printf("查询成功!\n");
msg.mtype = M_SUCCESS;
}
msg.acc = accResult;
if(msgsnd(msgid2,&msg,sizeof(msg.acc),) == -) perror("msgsnd"),exit(-); }
else if(msg.mtype == M_TRANSF){
struct Account accto;
accMove = msg.acc;
if(msgrcv(msgid1,&msg,sizeof(struct Account),,) == -) perror("msgrcv"),exit(-);
accto = msg.acc;
int tra = moveMoney(accMove,accto,&accResult);
if(tra == -){
printf("没有此ID\n");
msg.mtype = M_FAILED;
}
else if(tra == ){
printf("转账失败\n");
msg.mtype = M_FAILED;
}
else if(tra == ){
printf("余额不足\n");
msg.mtype = M_FAILED;
}
else{
printf("转账成功\n");
msg.mtype = M_SUCCESS;
}
msg.acc = accResult;
if(msgsnd(msgid2,&msg,sizeof(struct Account),) == -) perror("msgsnd"),exit(-); }
}
return ;
}
client.c:
/* 客户端*/
#include <stdio.h>
#include "bank.h"
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <string.h> static int msgid1;//定义两个接受消息队列的id的变量
static int msgid2;
//获取消息队列函数,
void getID(){
msgid1 = msgget(key1,);
if(msgid1 == -){
perror("获取消息队列1失败");
exit(-);
}
msgid2 = msgget(key2,);
if(msgid2 == -){
perror("获取消息队列2失败");
exit(-);
}
}
//开户函数
void createUser(){
struct Account acc;
printf("请输入用户名:\n");
scanf("%s",acc.name);
printf("请输入密码:\n");
scanf("%s",acc.password);
printf("请输入金额:\n");
scanf("%d",&acc.balance);
struct Msg msg = {M_OPEN,acc};
//获取消息队列
getID();
//将消息发送到消息队列1中
msgsnd(msgid1,&msg,sizeof(msg.acc),);
//接受消息队列2中的消息
msgrcv(msgid2,&msg,sizeof(msg.acc),,);
if(msg.mtype == M_SUCCESS){
printf("开户成功!\n");
printf("您的ID为:%d\n",msg.acc.id);
}
else{
printf("开户失败!\n");
}
}
//销户
void destroyUser(){
struct Account acc;
printf("请输入需要销户的ID:");
scanf("%d",&acc.id);
getchar();
struct Msg msg;
msg.mtype = M_DESTROY;
msg.acc = acc;
//获取消息ID
getID();
//将消息发送到消息队列1中
if(msgsnd(msgid1,&msg,sizeof(msg.acc),) == -) perror("msgsnd"),exit(-);
//接收服务端消息
if(msgrcv(msgid2,&msg,sizeof(msg.acc),,) == -) perror("msgrcv"),exit(-);
if(msg.mtype == M_SUCCESS)
printf("销户成功\n");
else
printf("销户失败\n");
}
//存钱
void saveMoney(){
struct Account acc;
printf("请输入您的ID:");
scanf("%d",&acc.id);
getchar();
printf("请输入您需要存的钱数:");
scanf("%lf",&acc.balance);
getchar(); getID();
struct Msg msg = {M_SAVE,acc};
if(msgsnd(msgid1,&msg,sizeof(acc),) == -) perror("msgsnd"),exit(-);
if(msgrcv(msgid2,&msg,sizeof(acc),,) == -) perror("msgrcv"),exit(-);
if(msg.mtype == M_SUCCESS){
printf("存钱成功\n");
printf("您的余额为:%lf\n",msg.acc.balance);
}
else
printf("存钱失败!\n");
}
//取钱
void getMoney(){
struct Account acc;
printf("请输入您的ID:");
scanf("%d",&acc.id);
getchar();
printf("请输入您想取的金额:");
scanf("%lf",&acc.balance); getID();
struct Msg msg = {M_TAKE,acc}; if(msgsnd(msgid1,&msg,sizeof(acc),) == -) perror("msgsnd"),exit(-);
if(msgrcv(msgid2,&msg,sizeof(acc),,) == -) perror("msgrcv"),exit(-);
if(msg.mtype == M_SUCCESS){
printf("取钱成功\n");
printf("您的余额为:%lf\n",msg.acc.balance);
}
else
printf("取钱失败!\n"); }
//查询
void checkMoney(){
struct Account acc;
printf("请输入您的ID:");
scanf("%d",&acc.id);
getchar(); struct Msg msg = {M_QUERY,acc}; getID();
if(msgsnd(msgid1,&msg,sizeof(acc),) == -) perror("msgsnd"),exit(-);
if(msgrcv(msgid2,&msg,sizeof(acc),,) == -) perror("msgrcv"),exit(-);
if(msg.mtype == M_SUCCESS){
printf("查询成功\n");
printf("您的余额为:%lf\n",msg.acc.balance);
}
else
printf("查询失败!\n");
}
//转账
void moveMoney(){
struct Account acc;
printf("请输入你的ID:%d:");
scanf("%d",&acc.id);
getchar();
printf("请输入你需要转账的金额:");
scanf("%lf",&acc.balance);
getchar(); getID(); struct Msg msg;
msg.mtype = M_TRANSF;
msg.acc = acc; if(msgsnd(msgid1,&msg,sizeof(struct Account),) == -) perror("msgsnd"),exit(-); printf("请输入需要转入的ID:");
scanf("%d",&acc.id);
msg.mtype = M_TRANSF;
msg.acc = acc;
if(msgsnd(msgid1,&msg,sizeof(struct Account),) == -) perror("msgsnd"),exit(-); if(msgrcv(msgid2,&msg,sizeof(struct Account),,) == -) perror("msgrcv"),exit(-); if(msg.mtype == M_SUCCESS){
printf("转账成功!您的余额为:%lf",msg.acc.balance);
}
else
printf("转账失败!\n");
} //客户端界面
void mainPage(){
while(){
printf(" 欢迎使用迷你ATM机\n");
printf("---------------------\n");
printf("[1] 开户");
printf(" [2] 销户\n");
printf("[3] 存钱");
printf(" [4] 取钱\n");
printf("[5] 查询");
printf(" [6] 转账\n");
printf("[0] 退出\n");
printf("---------------------\n");
printf("请选择:\n");
int num = ;
scanf("%d",&num);
switch(num){
case :createUser();break;
case :destroyUser();break;
case :saveMoney();break;
case :getMoney();break;
case :checkMoney();break;
case :moveMoney();break;
case :printf("谢谢使用,再见!\n");return ;
default:printf("输入错误\n");
}
}
}
int main(){
mainPage();
return ;
}
dao.c:
#include "dao.h"
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
//定义一个文件来存储帐号
const char* ID_FILE = "id.dat";
//生成不重复的帐号
int generator_id(){
static int x = ;
if(access(ID_FILE,F_OK)==-){//判断文件是否存在,不存在返回-1
//不存在就创建
int fd = open(ID_FILE,O_WRONLY|O_CREAT|O_EXCL,);
if(fd == -){
perror("文件打开失败");
return -;
}
write(fd,&x,sizeof(x));//写入文件
close(fd);
return x;
}
//如果文件存
int fd = open(ID_FILE,O_RDWR);
if(fd == -){
perror("文件打开失败");
return -;
}
//将文件中的数值读到x中
read(fd,&x,sizeof(x));
x++;//保证帐号唯一
//将读写位置置到文件开始头
lseek(fd,,SEEK_SET);
//再将x的值写到文件中,覆盖原来的x
write(fd,&x,sizeof(x));
close(fd);
return x;
} //将一个新帐号 存到文件中
int createUser(struct Account acc){
char filename[]={};
sprintf(filename,"%d.dat",acc.id);//为每个帐号建立一个文件
int fd = open(filename,O_WRONLY|O_CREAT|O_EXCL,);
if(fd == -){
perror("创建帐户文件失败");
return -;
}
if(write(fd,&acc,sizeof(acc)) < ){
return -;
}
close(fd);
printf("创建用户成功\n");
return ;
} //销户功能
int destroyUser(struct Account acc){
char filename[];
sprintf(filename,"%d.dat",acc.id);
if(access(filename,F_OK) == -)
return -;//返回 -1 表示没有这个ID
if(remove(filename) == -)
return ;//返回 0 表示 销户失败
else
return ;//返回 1 表示 销户成功 } //存钱功能
int saveMoney(struct Account acc, struct Account *p){
char filename[];
sprintf(filename,"%d.dat",acc.id);
if(access(filename,F_OK) == -)
return -;
int fd;
if((fd = open(filename,O_RDWR)) == -) perror("open"),exit(-); if(read(fd,p,sizeof(struct Account)) < ) perror("read"),exit(-); p->balance += acc.balance; //printf("存过钱:%lf",p->balance);
lseek(fd,,SEEK_SET);
if(write(fd,p,sizeof(struct Account)) < )
return ;
else
return ;
close(fd);
} //取钱
int getMoney(struct Account acc, struct Account *p){
char filename[];
sprintf(filename,"%d.dat",acc.id);
if(access(filename,F_OK) == -)
return -;
int fd;
if((fd = open(filename,O_RDWR)) == -) perror("open"),exit(-); if(read(fd,p,sizeof(struct Account)) < ) perror("read"),exit(-); if(p->balance < acc.balance){
return ; //余额不足
} p->balance -= acc.balance;
//printf("存过钱:%lf",p->balance);
lseek(fd,,SEEK_SET);
if(write(fd,p,sizeof(struct Account)) < )
return ;
else
return ;
close(fd);
} //查询余额功能
int checkMoney(struct Account acc, struct Account *p){
char filename[];
sprintf(filename,"%d.dat",acc.id);
if(access(filename,F_OK) == -)
return -;
int fd;
if((fd = open(filename,O_RDWR)) == -) perror("open"),exit(-); if(read(fd,p,sizeof(struct Account)) < )
return ;
else
return ;
close(fd);
} //转账功能 acc1 --> from acc2 --> to
int moveMoney(struct Account acc1, struct Account acc2, struct Account *p){
char filename[];
sprintf(filename,"%d.dat",acc1.id);
if(access(filename,F_OK) == -)
return -;
int fdfrom,fdto;
if((fdfrom = open(filename,O_RDWR)) < ) perror("open"),exit(-);
if(read(fdfrom,p,sizeof(struct Account)) < ) return ;
//判断金额是否足够
if(p->balance < acc1.balance) return ;
//判断转入的用户是否存在
sprintf(filename,"%d.dat",acc2.id);
if(access(filename,F_OK) == -)
return -; p->balance -= acc1.balance;
lseek(fdfrom,,SEEK_SET);
if(write(fdfrom,p,sizeof(struct Account)) < ) perror("write"),exit(-);
close(fdfrom); if((fdto = open(filename,O_RDWR)) < ) perror("open"),exit(-);
if(read(fdto,&acc2,sizeof(struct Account)) < ) perror("open"),exit(-);
acc2.balance += acc1.balance;
lseek(fdto,,SEEK_SET); //需要把文件指针移动到文件开头
if(write(fdto,&acc2,sizeof(struct Account)) < ){
return ;
close(fdto);
}
else{
close(fdto);
return ;
} }
link:
server:
gcc server.c bank.c -o server
client:
gcc client.c bank.c -o client
open:
gcc open.c bank.c dao.c -o open
【C】——C模拟atm取款机的更多相关文章
-
java基础:模拟ATM取款机
package com.atm; import java.util.Scanner; /** * ATM类实现 * * @author 向往的生活 */ public class ATM { publ ...
-
语言模拟ATM自动取款机系统
C语言实验报告 题目名称:C语言模拟ATM自动取款机系统 C语言模拟实现ATM自动取款机功能:输入密码,余额查询,取款,存款,转账,修改密码,退出功能: 代码实现的功能: 账号及密码输入: ...
-
ATM取款机的数据库模拟开发和实战总结
一.ATM实战开发的简介. 学习了几天的Oracle,开始着手用数据库PL/SQL语言做一个简单的ATM取款机业务,主要是为了巩固数据库的知识,并非真正的去实现高端的业务.有兴趣的可以看看,希望对同胞 ...
-
ATM取款机模拟——数据结构课设
今天帮人写的第二篇课设 . ;-) 机智的窝 要求:大概说一下吧,就是要创建一个用户(初始化一账户),模拟ATM的业务(取款,100的整数倍,改密 码,查剩余金额.等等,各 ...
-
Oracle实战训练——ATM取款机业务
ATM取款机的数据库模拟开发和实战总结 一.ATM实战开发的简介. 学习了几天的Oracle,开始着手用数据库PL/SQL语言做一个简单的ATM取款机业务,主要是为了巩固数据库的知识,并非真正的去实现 ...
-
01、模拟ATM机界面程序
一.概述 设计一个简单的模拟自动取款机ATM界面的程序,实现用户登录及取款等功能. 二.需求分析 (1)模拟自动取款机ATM界面,有常用功能. (2)主要功能包括;用户输入密码登录主界面.取款功能.取 ...
-
大话JS面向对象之开篇万物皆对象------(ATM取款机引发的深思)
一,总体概要 OO(面向对象)概念的提出是软件开发工程发展的一次革命,多年来我们借助它使得很多大型应用程序得以顺利实现.如果您还没有掌握并使用OO进行程序设计和开发,那么您无疑还停留在软件开发的石器时 ...
-
第一周:设计一个简易ATM取款机简易程序(2)
1.了解用户对ATM取款机功能需求如下: 2.新建一个login函数使用for循环方法和if选择方法编写登陆界面用来及设置ATM内用户的金额和取款机内的金额: 3.使用新建函数方法及if选择方法编写登 ...
-
从零开始学Python04作业源码:模拟ATM电子银行(仅供参考)
bin目录:程序启动入口 ATM_start.py: #!/usr/bin/python # -*- coding: utf-8 -*- # 模拟ATM电子银行+登录账户权限控制+管理员管理模块 # ...
随机推荐
-
设置eclipse中自动添加get,set的注释为字段属性的注释
一:说明 首先具体来看一下是什么效果,上图可能会更清楚一点 就是在get/set中自动加上属性的注释,那我们要怎么配置呢? 二:配置 2.1:下载附件 下载附件 2.2:替换class 原生的ecli ...
-
详解Node解析URL网址
前提给大家声明一下,我操作的环境是Mac终端下操作的.(前提是你先要下载好node.js) 说道URL 恐怕都不陌生,但是要说URL,就 必须先说下URI URI是统一资源标识符,是一个用于标识某一互 ...
-
C语言的傻瓜式随笔(二):全局变量、预编译、goto
函数的作用:可以实现代码的重用. 函数只需要定义1次,那么函数中的代码就可以随意的调用. -某不知出处的基本概念 学而时习之,如有误笔,请指正 一.goto跳转语句 goto在C语言的作用 ...
-
hdu-1789-Doing Homework again
/* Doing Homework again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
-
javascript去掉字符串前后空格
使用场景 当我们进行一些页面编辑时,字符串前后的空格,通常是无效的.因此需要在获取信息时,进行过滤. 比如: 输入:[空格][空格]a[空格]b[空格][空格][空格] 得到:a[空格]b 代码如下: ...
-
web 前端:连接mysql中文乱码问题的解决办法
当使用tomcat部署servlet连接时,总是出现各种原因的中文乱码问题.有的是因为mysql的默认字符集的问题,有的是客户端的字符配置问题. 现在对于这两种问题进行配置,来解决乱码. 服务器端(m ...
-
Android再次激活Activity时触发事件用于列表重新读取载入
@Override protected void onResume(){ super.onResume(); getList(); } 重载 onResume() 方法
-
PPTP --VPN配置
测试:1:根据上面的步骤4,在路由器里查看状态:2:手机热点,共享给你电脑,电脑拨号,进行测试. 参考:http://jingyan.baidu.com/article/90808022ddd6a ...
-
Raspberry Pi Kernel Compilation 内核编译官方文档
elinux.org/Raspberry_Pi_Kernel_Compilation#Use_the_provided_compiler Software & Distributions: S ...
-
Ubuntu安装微信开发者工具
参考教程:https://ruby-china.org/topics/30339 1.下载nw sdk $ wget -c http://dl.nwjs.io/v0.15.3/nwjs-sdk-v0. ...