两个SQL数据库服务器,一个在公网服务器上,一个在本地!能不能关联操作...
发布网友
发布时间:2022-05-02 02:51
我来回答
共8个回答
热心网友
时间:2022-04-27 09:49
接到一个任务,有2台机器,其中有一台机器A有每天数据库的备份,我想另外的一台机器B定时从A中copy到B的制定目录,A不共享数据库备份的目录。考虑到FTP方式无法跨越NAT(网络地址转换),而HTTP方式在安全性和可靠性方面都得不到保证,在文件较大时也会有一定的*。决定采用一种基于HTTP协议,编写客户端和服务器端程序,在一个客户端用HttpWebRequest对象向指定的URL发送POST和GET请求,在服务器端通过程序接受请求,进行文件传输,这样,发送和接收都由自己编写的程序进行控制,可以方便地实现诸如身份验证、数据加密和断点续传等功能,同时可以穿越防火墙和NAT。这样做就可以实现在.Net中跨Internet的文件加密传输。
在.net中实现跨Internet的文件加密传输的程序源码
一、数据上传
1.客户端代码
//从文本框中获得文件的全称,含路径名
string strFilePath=txUpFile.Text;
//获得文件的长度
FileInfo fi=new FileInfo(strFilePath);
long lFileLength=fi.Length;
//获得文件名
string strFileName=strFilePath.Substring(strFilePath.LastIndexOf("\\")+1);
//创建HttpWebRequest对象,传入路径名,将文件名和长度作为参数传给服务器端
HttpWebRequest objRequest=(HttpWebRequest)HttpWebRequest.Create(string.
Format(@"{0}?FileName={1}&FileLength={2}",txUpURL.Text,strFileName,
lFileLength.ToString()));
//定义Request对象的方法为"post"
objRequest.Method="POST";
//定义Request对象的内容类型为"application/octet-stream"
objRequest.ContentType="application/octet-stream";
//定义请求内容的长度
objRequest.ContentLength=((int)(lFileLength/8+1))*8;
//定义一个请求的流
Stream reqStream=objRequest.GetRequestStream();
//用DES算法加密此请求流
byte[] desKey={1,0,1,1,5,6,7,8};
byte[] desIV={1,2,3,4,5,6,7,8};
DES des=new DESCryptoServiceProvider();
CryptoStream encStream=new CryptoStream(reqStream,des.CreateEncrytor(desKey,desIV),CryptoStreamMode.Write);
//定义内存缓冲区用于文件的读写
int iBufferSize=4095;
byte[] buffer=new byte[iBufferSize];
//打开文件,准备读取
FileStream fileStream=new FileStream(strFilePath,FileMode.Open,FileAccess.Read);
int iReadLength=0;
//将文件内容读入缓冲区
iReadLength=fileStream.Read(buffer,0,buffer.Length);
while(iReadLength!=0) {
//将读出的文件内容写入加密流
encStream.Write(buffer,0,iReadLength);
iReadLength=fileStream.Read(buffer,0,buffer.Length);
}
//关闭请求的流
encStream.Close();
reqStream.Close();
fileStream.Close();
//向服务器提出请求并获得结果3
HttpWebResponse sp=(HttpWebResponse)objRequest.GetResponse();
string strContent="";
int iLen=(int)sp.ContentLength;
if(iLen>0) {
//将结果流写入到二进制流bContent中
Stream resStream=sp.GetResponseStream();
byte[] bContent=new byte[sp.ContentLength];
resStream.Read(bContent,0,iLen);
sp.Close();
//由于结果是一个二进制数据,必须将结果解码成字符串
char[] charContent=new char[sp.ContentLength];
Text.Decoder dc=Text.Encoding.UTF8.GetDecoder();
int charLen=dc.GetChars(bContent,0,bContent.Length,charContent,0);
foreach(char c in charContent) strContent+=c.ToString();
}
2.服务器端代码
//判断请求的ContentType,过滤非法请求
if(Request.ContentType!="application/octet-stream") return;
//获得上传得文件名和长度
string strFileName=Request.QueryString["FileName"];
int iFileLength=Request.TotalBytes;
//构造服务器端文件名
string strFilePath=Server.MapPath(".")+IO.Path.DirectorySeparatorChar+"Upload"+IO.Path.DirectorySeparatorChar+strFileName;
//判断文件是否存在
if(File.Exists(strFilePath)) {
//如果文件存在,返回文件名和文件长度
FileInfo fi=new FileInfo(strFilePath);
long lFileLength=fi.Length;
Response.Write("File["+strFileName+"]Exists!Length="+lFileLength.ToString());
Response.End();
}
//如果文件不存在,打开文件流创建该文件
FileStream fileStream=File.Create(strFilePath,iFileLength);
//用DES算法解密该文件流
byte[] desKey={1,0,1,1,5,6,7,8};
byte[] desIV={1,2,3,4,5,6,7,8};
DES des=new DESCryptoServiceProvider();
CryptoStream desStream=new CryptoStream(fileStream,des.CreateDecryptor(desKey,desIV),CryptoStreamMode.Write);
//定义内存缓冲区大小
int iBufferSize=4095;
//读取请求流并写入文件中
byte[] buffer=new byte[iBufferSize];
int iReadLength=0;
iReadLength=Request.InputStream.Read(buffer,0,buffer.Length);
while(iReadLength>0) {
desStream.Write(buffer,0,iReadLength);
desStream.Flush();
iReadLength=Request.InputStream.Read(buffer,0,buffer.Length);
}
desStream.Flush();
desStream.Close();
fileStream.Close();
//返回结果
Response.Write("File["+strFileName+"]UploadSuccess!");
Response.End();
二、数据下载
1.客户端代码
//获取下载文件名
string strFileName=txDownFile.Text;
//定义文件偏移量
int iOffset=0;
//创建HttpWebRequest对象,传入路径名,将文件名和偏移量作为参数传给服务器
HttpWebRequest objRequest=(HttpWebRequest)HttpWebRequest.Create(string.
Format(@"{0}?FileName={1}&Offset={2}",txDownURL.Text,strFileName,iOffset));
//定义Request对象的方法为"get"
objRequest.Method="GET";
//定义Request对象的内容类型为"application/octet-stream"
objRequest.ContentType="application/octet-stream"
//获得请求结果
HttpWebResponse sp=(HttpWebResponse)objRequest.GetResponse();
Stream resStream=sp.GetResponseStream();
string strFilePath=txDownPath.Text;
//如果文件存在,则删除
if(File.Exists(strFilePath)) {
File.Delete(strFilePath);
}
//创建文件
int iBufferSize=4095;
FileStream fileStream=File.Create(strFilePath);
//解密返回的流
byte[] desKey={1,0,1,1,5,6,7,8};
byte[] desIV={1,2,3,4,5,6,7,8};
DES des=new DESCryptoServiceProvider();
CryptoStream decStream=new CryptoStream(resStream,des.CreateDecryptor(desKey,desIV),CryptoStreamMode.Read);
byte[] buffer=new byte[iBufferSize];
int iReadLength=0;
//读取返回流
iReadLength=decStream.Read(buffer,0,buffer.Length);
while(iReadLength>0) {
//写入文件流中
fileStream.Write(buffer,0,iReadLength);
iReadLength=decStream.Read(buffer,0,buffer.Length);
}
fileStream.Flush();
decStream.Close();
fileStream.Close();
resStream.Close();
return "File["+strFileName+"]Download Success!";
2.服务器端代码
//获得上传的文件名和偏移量
string strFileName=Request.QueryString["FileName"];
long lOffset=Convert.ToInt64(Request.QueryString["Offset"]);
//构造文件全路径名
string strFilePath=Server.MapPath(".")+IO.Path.DirectorySeparatorChar+"Download"+IO.Path.DirectorySeparatorChar+strFileName;
//若文件不存在,则返回错误信息
if(!File.Exists(strFilePath)) {
Response.Clear();
Response.Write("File["+strFileName+"]Not Exists!");
Response.End();
}
//打开文件
IO.FileStream fileStream=new IO.FileStream(strFilePath,IO.FileMode.Open,IO.FileAccess.Read,IO.FileShare.Read);
//根据上传的偏移量参数设置偏移量
if(lOffset>0)
fileStream.Seek(lOffset,IO.SeekOrigin.Begin);
//定义输出流
Stream resStream=Response.OutputStream;
//用DES算法加密此数据流
byte[] desKey={1,0,1,1,5,6,7,8};
byte[] desIV={1,2,3,4,5,6,7,8};
DES des=new DESCryptoServiceProvider();
CryptoStream encStream=new CryptoStream(resStream,des.CreateDecryptor(desKey,desIV),CryptoStreamMode.Write);
//定义输出文件流的头
Response.ContentType="application/octet-stream";
Response.AddHeader("Content-Disposition","attachment;filename="+strFileName);
int iBufferSize=4095;
byte[] buffer=new byte[iBufferSize];
int iReadLength=0;
//读取文件
iReadLength=fileStream.Read(buffer,0,buffer.Length);
while(iReadLength>0) {
//写入输出流
encStream.Write(buffer,0,iReadLength);
iReadLength=fileStream.Read(buffer,0,buffer.Length);
}
encStream.Flush();
resStream.Flush();
//关闭流
encStream.Close();
resStream.Close();
fileStream.Close();
//Response.Flush();
//结束输出
Response.End();
参考资料:http://blog.csdn.net/hias_asia/archive/2008/03/23/2210591.aspx
热心网友
时间:2022-04-27 11:07
那就用一个数据库服务器,2套程序同连一个数据库,不就可以操作了?
热心网友
时间:2022-04-27 12:41
我知道oracle有个rac,对于多个oracle服务器,可以让用户不管操作哪个oracle服务器都一样(因为oracle支持网格计算),例如:10.182.2.37和10.182.2.37的主机上分别安装了oracle服务器,这两个oracle服务器做rac后,用plsql操作时,不管连接10.182.2.37还10.182.2.36都能操作同一张表,同一个存储过程。。。,总之就操作同一个数据库一样,不知道sqlservic有没有这样的功能啊
热心网友
时间:2022-04-27 14:33
天啊,哪有那么麻烦,同步不久可以了,数据库快照,复制
或者用dts包和作业来做
热心网友
时间:2022-04-27 16:41
那程序最好再本地运行
A 公网服务器 , B 局域网服务器 , C 客户端
可以选择程序再B或C上运行
热心网友
时间:2022-04-27 19:05
我有个很初级的想法
这种情况下*服务器访问本地服务器很需要固定ip,而且安全也比较麻烦
我觉得应该把大部分功能放在本地服务器上,在*服务器上建一个特殊表,用来保存操作记录,本地服务器间隔一点时间就访问这个操作记录表,在本地也执行一遍同样的操作,这样就实现了对本地的同步
本地操作完成之后呢,就将同样的操作直接连接*服务器在执行一次,这样双方都可以同步了
值得主意的是不要形成循环,需要一个标记
同步失败的处理
热心网友
时间:2022-04-27 21:47
若在系统设计初期应将两个数据库合并为一个,置于本地,建库时可设计通过表名的前缀来区分不同的功能;例如网站私有表了加前缀“site_”,程序表可加“app_”,公共表可加“pub_”
若是使用中的系统,可将两个数据库置于本地同一台服务器上,得有个固定IP,(可向接入商申请,每年约600RMB);这样c#的程序可以很方便的访问本地网络中的数据;网站中的数据一般不会比应用程序中的更重要,可以让.net网站远程访问数据,为提高安全性应将.net数据库连接字符串加密;若有条件,可使用VPN
优点:可降低服务器成本,提升本地系统服务质量和安全性
缺点:易受当地公网性能影响造成网站打开速度急剧下降;对网站来说安全性不好
措施:建议网站服务器也放在本地,可以获得更高的性能和安全性。
热心网友
时间:2022-04-28 00:45
关注 学习