话不多说,进入主题,我们先来看下Stream首页界面,是不是很简洁,使用起来也很简单。
从界面上可以看出来,功能还是齐全的,可以构建请求,设置抓包模式,还有嵌入的小工具。
1|0构建请求
我们先从构建请求说起,构建请求,包含了接口的八种方式,在这里,再温习一下,这八种请求方式的用途。
1、Get 向特定资源发出请求(请求指定页面信息,并返回实体主体);
2、Post 向指定资源提交数据进行处理请求(提交表单、上传文件),又可能导致新的资源的建立或原有资源的修改;
3、Put 向指定资源位置上上传其最新内容(从客户端向服务器传送的数据取代指定文档的内容);
4、Head 与服务器索与get请求一致的相应,响应体不会返回,获取包含在小消息头中的原信息(与get请求类似,返回的响应中没有具体内容,用于获取报头);
5、Delete 请求服务器删除request-URL所标示的资源(请求服务器删除页面);
6、Trace 回显服务器收到的请求,用于测试和诊断;
7、opions 返回服务器针对特定资源所支持的HTML请求方法 或web服务器发送测试服务器功能(允许客户端查看服务器性能);
8、Connect >服务器端可以采用多线程处理客户请求,例如:
package threadPool;
import javaioBufferedReader;
import javaioIOException;
import javaioInputStream;
import javaioInputStreamReader;
import javaioOutputStream;
import javaioPrintWriter;
import javanetServerSocket;
import javanetSocket;
import javautilconcurrentExecutorService;
import javautilconcurrentExecutors;
public class ThreadPoolServer {
private int port = 8000;
private ServerSocket serverSocket;
private ExecutorService executorService; //线程池
private final int POOL_SIZE = 4; //单个CPU时线程池中的工作线程数目
public ThreadPoolServer() throws IOException{
serverSocket = new ServerSocket(port);
//创建线程池
//Runtime 的availableProcessors()方法返回当前系统CPU的数目
//系统CPU越多,线程池中的工作线程数目越多
executorService = ExecutorsnewFixedThreadPool(RuntimegetRuntime()availableProcessors()POOL_SIZE);
Systemoutprintln("服务器已启动!!");
}
public void service(){
while(true){
Socket socket = null;
try{
socket = serverSocketaccept();
executorServiceexecute(new Handler(socket));
}catch(IOException e){
eprintStackTrace();
}
}
}
public static void main(String[] args) {
try {
new ThreadPoolServer()service();
} catch (IOException e) {
eprintStackTrace();
}
}
}
class Handler implements Runnable {
private Socket socket;
public Handler(Socket socket) {
thissocket = socket;
}
private PrintWriter getWriter(Socket socket) throws IOException {
OutputStream socketOut = socketgetOutputStream();
return new PrintWriter(socketOut, true);
}
private BufferedReader getReader(Socket socket) throws IOException {
InputStream socketIn = socketgetInputStream();
return new BufferedReader(new InputStreamReader(socketIn));
}
public String echo(String msg) {
return "echo:" + msg;
}
@Override
public void run() {
try {
Systemoutprintln("New connection accepted:" + socketgetInetAddress() + ":" + socketgetPort());
BufferedReader br = getReader(socket);
PrintWriter pw = getWriter(socket);
String msg = null;
while ((msg = brreadLine()) != null) {
Systemoutprintln(msg);
pwprintln(echo(msg));
if (msgequals("bye")) {
break;
}
}
} catch (IOException e) {
eprintStackTrace();
} finally {
try {
if (socket != null)
socketclose();
} catch (IOException e) {
eprintStackTrace();
}
}
}
}服务端:
class mTcpServer
{
class server
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
Thread newThread;
try
{
serverTcpListener = new TcpListener(localAddr, port);
serverTcpListenerStart();
while (true)
{
ConsoleWrite("Waiting for a connection ");
client = serverTcpListenerAcceptTcpClient();
ConsoleWriteLine("Connected!");
newThread = new Thread(new ThreadStart(newScream));
newThreadStart();
}
}
catch (SocketException e)
{
ConsoleWriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients
ConsoleWriteLine("Stop listening for new clients");
serverTcpListenerStop();
}
ConsoleWriteLine("\nHit enter to continue");
ConsoleRead();
}
static Int32 port = 9050;
static IPAddress localAddr = IPAddressParse("127001");
static TcpListener serverTcpListener = null;
static Byte[] bytes = new Byte[256];
static String data = null;
static TcpClient client;
static void newScream()
{
data = null;
NetworkStream stream = clientGetStream();
streamWrite(EncodingASCIIGetBytes("Connected!"), 0, 10);
int i;
while ((i = streamRead(bytes, 0, bytesLength)) != 0)
{
data = SystemTextEncodingASCIIGetString(bytes, 0, i);
ConsoleWriteLine("Received: {0}", data);
data = dataToUpper();
byte[] msg = SystemTextEncodingASCIIGetBytes(data);
streamWrite(msg, 0, msgLength);
ConsoleWriteLine("Sent: {0}", data);
}
}
}
}
客户端:
using System;
using SystemNet;
using SystemNetSockets;
using SystemText;
namespace mTcpClint
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
class client
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: 在此处添加代码以启动应用程序
//
byte[] data = new byte[1024];
//Socket newclient = new Socket(AddressFamilyInterNetwork, SocketTypeStream, ProtocolTypeTcp);
ConsoleWrite("please input the server ip:");
string ipadd = ConsoleReadLine();
ConsoleWriteLine();
ConsoleWrite("please input the server port:");
int port = ConvertToInt32(ConsoleReadLine());
IPEndPoint ie = new IPEndPoint(IPAddressParse(ipadd), port);//服务器的IP和端口
TcpClient newclient;
newclient = new TcpClient();
newclientConnect(ipadd, port);
int recv = newclientClientReceive(data);
string stringdata = EncodingASCIIGetString(data, 0, recv);
ConsoleWriteLine(stringdata);
while (true)
{
string input = ConsoleReadLine();
if (input == "exit") break;
newclientClientSend(EncodingASCIIGetBytes(input));
data = new byte[1024];
recv = newclientClientReceive(data);
stringdata = EncodingASCIIGetString(data, 0, recv);
ConsoleWriteLine(stringdata);
}
ConsoleWriteLine("disconnect from server");
newclientClientShutdown(SocketShutdownBoth);
newclientClose();
}
}
}可以处理的,步骤为:
1客户端与服务器连(用Socket通讯)
2客户端向处服务器发送SQL语句,如搜索一个表的数据
3服务器接到请求,执行SQL语句返回一个DataTable
4服务器将这个DataTable进行序列化、并且压缩
5服务器将序列化和压缩后的byte[] msg数组传给客户端
6客户端收到byte[] msg数组先进行解压缩、和反序列化为DataTable
7再将DataTable通过DataSet和SqlDataAdapterUpdate(Table)存在SQL中
下面我只给一些关键的代码,我有实现过的
第一步客户端==》连接服务器并通讯,主要是发送SQL给服务器返回一个DataTable表
using System;
using SystemCollectionsGeneric;
using SystemComponentModel;
using SystemData;
using SystemDrawing;
using SystemLinq;
using SystemText;
using SystemWindowsForms;
using SystemNet;
using SystemNetSockets;
using SystemXml;
using SystemXmlSerialization;
using SystemIO;
using SystemIOCompression;
namespace Client
{
public partial class FormClient : Form
{
DataTable dt;
public FormClient()
{
InitializeComponent();
}
private void ClientTest(string str)
{
Socket client;
String returnData;
byte[] buf = new byte[9991024]; //此处可能有些问题
//IPAddress local = IPAddressParse("1162583127");
IPAddress local = IPAddressParse("127001");//可改为远程IP地址
IPEndPoint iep = new IPEndPoint(local, 6060);
try
{
client = new Socket(AddressFamilyInterNetwork, SocketTypeStream, ProtocolTypeTcp);
clientConnect(iep);
}
catch (SocketException)
{
ConsoleWriteLine("无法连接到服务器!");
return ;
}
//输入exit,可以断开与服务器的连接
if (str == "")
{
return;
}
//发送SQL语句给服务器
clientSend(EncodingUnicodeGetBytes(str));
//得到实际收到的字节总数
Int32 rec = clientReceive(buf);
ConsoleWriteLine(EncodingASCIIGetString(buf, 0, rec));
//接收服务器返回的数据
returnData = SystemTextEncodingUnicodeGetString(buf,0,rec);
//将returnData解压缩后,再反序列化转成DataTable dt = DeserializerDataTable(Decompress(returnData));
ConsoleWriteLine("断开与服务器的连接");
clientClose();
dataGridView1DataSource = dt;
}
//将DataTable表反序列化
private DataTable DeserializerDataTable(string pXml)
{
StringReader strReader = new StringReader(pXml);
XmlReader xmlReader = XmlReaderCreate(strReader);
XmlSerializer serializer = new XmlSerializer(typeof(DataTable));
DataTable dt = serializerDeserialize(xmlReader) as DataTable;
return dt; }
//给服务器传SQL语句
private void buttonSearch_Click(object sender, EventArgs e)
{
string Sql = StringFormat("Select top {0} From Part Where CorpCode_='PT'", textBox1TextTrim()); ;
ClientTest(Sql);
}
#region 压缩和解压缩
public string Compress(string str)
{
byte[] buffer = EncodingUnicodeGetBytes(str);
MemoryStream ms = new MemoryStream();
using (GZipStream zip = new GZipStream(ms, CompressionModeCompress, true))
{
zipWrite(buffer, 0, bufferLength);
}
msPosition = 0;
MemoryStream outStream = new MemoryStream();
byte[] compressed = new byte[msLength];
msRead(compressed, 0, compressedLength);
byte[] gzBuffer = new byte[compressedLength + 4];
SystemBufferBlockCopy(compressed, 0, gzBuffer, 4, compressedLength);
SystemBufferBlockCopy(BitConverterGetBytes(bufferLength), 0, gzBuffer, 0, 4);
return ConvertToBase64String(gzBuffer);
}
//解压缩
public string Decompress(string compressedText)
{
byte[] gzBuffer = ConvertFromBase64String(compressedText);
using (MemoryStream ms = new MemoryStream())
{
int msgLength = BitConverterToInt32(gzBuffer, 0);
msWrite(gzBuffer, 4, gzBufferLength - 4);
byte[] buffer = new byte[msgLength];
msPosition = 0;
using (GZipStream zip = new GZipStream(ms, CompressionModeDecompress))
{
zipRead(buffer, 0, bufferLength);
}
return EncodingUnicodeGetString(buffer);
}
}
#endregion
}
}
第二步服务器收到SQL语句执行,并回传一个表给客户端
服务器接到请求,执行SQL语句返回一个DataTable
服务器将这个DataTable进行序列化、并且压缩
服务器将序列化和压缩后的byte[] msg数组传给客户端
using System;
using SystemCollectionsGeneric;
using SystemComponentModel;
using SystemData;
using SystemDrawing;
using SystemLinq;
using SystemText;
using SystemWindowsForms;
using SystemNet;
using SystemNetSockets; //可以使用套接字
using SystemThreading; //可以使用多线程
using SystemDataSqlClient;
using SystemXml;
using SystemXmlSerialization;
using SystemIO;
using SystemIOCompression;
namespace AppServer
{
public partial class FormApp : Form
{
public FormApp()
{
InitializeComponent();
}
private void FormApp_Load(object sender, EventArgs e)
{
// AppService instance = new AppService();
}
private void buttonStartService_Click(object sender, EventArgs e)
{
AppService();
}
private Socket server;
private Socket client;
private void AppService()
{
/
//本机IP
string name = DnsGetHostName();
IPHostEntry host = DnsGetHostByName(name);
IPAddress id= hostAddressList[0];
/
//IPAddress local = IPAddressParse("1921680100");
IPEndPoint iep = new IPEndPoint(IPAddressAny, 6060);
server = new Socket(AddressFamilyInterNetwork, SocketTypeStream, ProtocolTypeTcp);
// 将套接字与本地终结点绑定
serverBind(iep);
//在本地13000端口号上进行监听
serverListen(10);
while (true)
{
// 得到包含客户端信息的套接字
client = serverAccept();
//创建消息服务线程对象ClientService方法委托给线程
Thread newthread = new Thread(new ThreadStart(ClientService));
// 启动消息服务线程
newthreadStart();
}
}
private Int32 i;
private void ClientService()
{
Socket s = client;
String data = null;
String returnData = null;
byte[] bytes = new byte[1024];
while ((i = sReceive(bytes)) != 0)
{
//接收客户端的SQL
data = SystemTextEncodingUnicodeGetString(bytes, 0, i);
//将接到的String 执行SQL返回表
DBAccess obj = new DBAccess(); //专门传给SQL的类相当于DBHELP
DataTable dt = objFillData(data, "TEST", 1);//执行SQL返回表
//将返回的表转为String,并将returnData压缩
returnData = objCompress(objSerializeDataTableXml(dt));
byte[] msg = SystemTextEncodingUnicodeGetBytes(returnData);
// 发送数据表给客户端 sSend(msg);
if ((i = sReceive(bytes)) == 0)
continue;
}
//关闭套接字
sClose();
}
}
//DBAccess的部份代码
class DBAccess
{
#region DataTable序列化与反序列化
public string SerializeDataTableXml(DataTable dt)
{
StringBuilder sb = new StringBuilder();
XmlWriter writer = XmlWriterCreate(sb);
XmlSerializer serializer = new XmlSerializer(typeof(DataTable));
serializerSerialize(writer, dt);
writerClose();
return sbToString(); }
public DataTable DeserializerDataTable(string pXml)
{
StringReader strReader = new StringReader(pXml);
XmlReader xmlReader = XmlReaderCreate(strReader);
XmlSerializer serializer = new XmlSerializer(typeof(DataTable));
DataTable dt = serializerDeserialize(xmlReader) as DataTable;
return dt; }
#endregion
#region 压缩和解压缩
public string Compress(string str)
{
byte[] buffer = EncodingUnicodeGetBytes(str);
MemoryStream ms = new MemoryStream();
using (GZipStream zip = new GZipStream(ms, CompressionModeCompress, true))
{
zipWrite(buffer, 0, bufferLength);
}
msPosition = 0;
MemoryStream outStream = new MemoryStream();
byte[] compressed = new byte[msLength];
msRead(compressed, 0, compressedLength);
byte[] gzBuffer = new byte[compressedLength + 4];
SystemBufferBlockCopy(compressed, 0, gzBuffer, 4, compressedLength);
SystemBufferBlockCopy(BitConverterGetBytes(bufferLength), 0, gzBuffer, 0, 4);
return ConvertToBase64String(gzBuffer);
}
public string Decompress(string compressedText)
{
byte[] gzBuffer = ConvertFromBase64String(compressedText);
using (MemoryStream ms = new MemoryStream())
{
int msgLength = BitConverterToInt32(gzBuffer, 0);
msWrite(gzBuffer, 4, gzBufferLength - 4);
byte[] buffer = new byte[msgLength];
msPosition = 0;
using (GZipStream zip = new GZipStream(ms, CompressionModeDecompress))
{
zipRead(buffer, 0, bufferLength);
}
return EncodingUnicodeGetString(buffer);
}
}
#endregion
}
第三步调用DataSet和SqlDataAdapterUpdate(Table)存在SQL中,这个是传入一个DataGridView ,可在客户端中使用保存(部份代码,没有连接SQL数据库的)
#region 公共保存DataGridView
public bool DataGridViewSave(DataTable table,string tableName,string CorpCode)
{
string Sql = StringFormat("Select Top 0 From {0} Where CorpCode_='{1}' ", tableName, CorpCode);
SqlDataAdapter sda = new SqlDataAdapter(thisCreateCommand(Sql, null, 1));
SqlCommandBuilder scb = new SqlCommandBuilder(sda);
sdaUpdate(table);
thisClose();
return true;
}
#endregion
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)