3.5.3 发送和接收
下面是一个投票服务器用到的服务,用于处理服务器端接收到的投票信息的处理。
package com.suifeng.tcpip.chapter3.vote;
import java.util.HashMap;
import java.util.Map;
/**
* 服务器端对获取的投票信息进行处理
* @author Administrator
*
*/
public class VoteService
{
private Map<Integer, Long> results = new HashMap<Integer, Long>();
public VoteMsg handleRequest(VoteMsg msg)
{
if(msg.isResponse())
{
return msg;
}
// 设置投票信息返回标记
msg.setResponse(true);
// 投票人编号
int candidate = msg.getCandidate();
// 获取当前人的投票总数
Long count = results.get(candidate);
// 没有该候选人的投票信息
if(count == null)
{
count = 0L;
}
// 为该候选人投票
if(!msg.isInquery())
{
results.put(candidate, ++count);
}
// 设置投票总数
msg.setVoteCount(count);
return msg;
}
}
3.5.3.1 基于文本编解码和TCP套接字
客户端
package com.suifeng.tcpip.chapter3.vote;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import com.suifeng.tcpip.chapter3.framer.Framer;
import com.suifeng.tcpip.chapter3.framer.LengthFramer;
public class VoteTCPTextClient
{
private static final int CANDIDATE = 888;
/**
* @param args
* @throws IOException
* @throws UnknownHostException
*/
public static void main(String[] args) throws UnknownHostException,
IOException
{
if (args.length != 2)
{
throw new IllegalArgumentException(
"Parameter(s):<Server> <Port>");
}
// SerName or IP Address
String server = args[0];
// 获取端口号
int serverPort = Integer.parseInt(args[1]);
// 使用指定的服务器和端口创建Socket
Socket socket = new Socket(server, serverPort);
System.out.println("Connected to server ..... Sending echo String");
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
VoteMsgCoder coder = new VoteMsgTextCoder();
Framer framer = new LengthFramer(in);
// 第一个参数为true表示是查询消息,第二个参数为false表示非返回消息
VoteMsg msg = new VoteMsg(true,false,CANDIDATE,0);
// 使用文本方式进行编码
byte[] encodeMsg = coder.toWire(msg);
// 发起查询
System.out.println("++++++++++++++++++++++++++++++++++++++");
System.out.println("Sending Inquery("+encodeMsg.length+" bytes)");
System.out.println(msg);
framer.frameMsg(encodeMsg, out);
// 发起投票
msg.setInquery(false);
encodeMsg = coder.toWire(msg);
framer.frameMsg(encodeMsg, out);
System.out.println("Sending Inquery("+encodeMsg.length+" bytes)");
System.out.println(msg);
System.out.println("++++++++++++++++++++++++++++++++++++++");
System.out.println("");
// 接收查询返回
encodeMsg = framer.nextMsg();
msg = coder.fromWire(encodeMsg);
System.out.println("++++++++++++++++++++++++++++++++++++++");
System.out.println("Received Response("+encodeMsg.length+" bytes)");
System.out.println(msg);
// 接收投票返回
msg = coder.fromWire(framer.nextMsg());
System.out.println("Received Response("+encodeMsg.length+" bytes)");
System.out.println(msg);
System.out.println("++++++++++++++++++++++++++++++++++++++");
System.out.println("");
// 第二次发起投票
msg.setResponse(false);
encodeMsg = coder.toWire(msg);
System.out.println("Second Sending Inquery("+encodeMsg.length+" bytes)");
framer.frameMsg(encodeMsg, out);
System.out.println(msg);
System.out.println("++++++++++++++++++++++++++++++++++++++");
// 第二次接收投票返回
msg = coder.fromWire(framer.nextMsg());
System.out.println("Second Received Response("+encodeMsg.length+" bytes)");
System.out.println(msg);
System.out.println("++++++++++++++++++++++++++++++++++++++");
socket.close();
}
}
服务器端
package com.suifeng.tcpip.chapter3.vote;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import com.suifeng.tcpip.chapter3.framer.Framer;
import com.suifeng.tcpip.chapter3.framer.LengthFramer;
public class VoteTCPTextServer
{
public static void main(String[] args) throws IOException
{
if(args.length != 1)
{
throw new IllegalArgumentException("Parameter:<Port>");
}
// 获取服务器的端口
int serverPort = Integer.parseInt(args[0]);
// 创建用于客户端连接的SocketServer实例
ServerSocket server = new ServerSocket(serverPort);
System.out.println("Server has started!!!!");
VoteMsgCoder coder = new VoteMsgTextCoder();
VoteService service = new VoteService();
while(true)
{
Socket socket = server.accept();
System.out.println("Handling client at "+socket.getRemoteSocketAddress());
// 使用基于长度的成帧方法
Framer framer = new LengthFramer(socket.getInputStream());
byte[] req;
while((req = framer.nextMsg()) != null)
{
System.out.println("++++++++++++++++++++++++++++++++");
// 先解码投票信息,再进行处理
VoteMsg resMsg = service.handleRequest(coder.fromWire(req));
// 对投票信息编码后返回
framer.frameMsg(coder.toWire(resMsg), socket.getOutputStream());
System.out.println("Resonpnse message:"+resMsg);
System.out.println("++++++++++++++++++++++++++++++++");
System.out.println("");
}
socket.close();
}
}
}
启动服务器端,监听39393端口

启动客户端
再次查看服务器端

再次启动客户端

再查看服务器端

3.5.3.2 基于二进制编解码和TCP套接字
客户端
package com.suifeng.tcpip.chapter3.vote;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import com.suifeng.tcpip.chapter3.framer.Framer;
import com.suifeng.tcpip.chapter3.framer.LengthFramer;
public class VoteTCPBinaryClient
{
private static final int CANDIDATE = 888;
/**
* @param args
* @throws IOException
* @throws UnknownHostException
*/
public static void main(String[] args) throws UnknownHostException,
IOException
{
if (args.length != 2)
{
throw new IllegalArgumentException(
"Parameter(s):<Server> <Port>");
}
// SerName or IP Address
String server = args[0];
// 获取端口号
int serverPort = Integer.parseInt(args[1]);
// 使用指定的服务器和端口创建Socket
Socket socket = new Socket(server, serverPort);
System.out.println("Connected to server ..... Sending echo String");
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
VoteMsgCoder coder = new VoteMsgBinaryCoder();
Framer framer = new LengthFramer(in);
// 第一个参数为true表示是查询消息,第二个参数为false表示非返回消息
VoteMsg msg = new VoteMsg(true,false,CANDIDATE,0);
// 使用文本方式进行编码
byte[] encodeMsg = coder.toWire(msg);
// 发起查询
System.out.println("++++++++++++++++++++++++++++++++++++++");
System.out.println("Sending Inquery("+encodeMsg.length+" bytes)");
System.out.println(msg);
framer.frameMsg(encodeMsg, out);
// 发起投票
msg.setInquery(false);
encodeMsg = coder.toWire(msg);
framer.frameMsg(encodeMsg, out);
System.out.println("Sending Inquery("+encodeMsg.length+" bytes)");
System.out.println(msg);
System.out.println("++++++++++++++++++++++++++++++++++++++");
System.out.println("");
// 接收查询返回
encodeMsg = framer.nextMsg();
msg = coder.fromWire(encodeMsg);
System.out.println("++++++++++++++++++++++++++++++++++++++");
System.out.println("Received Response("+encodeMsg.length+" bytes)");
System.out.println(msg);
// 接收投票返回
msg = coder.fromWire(framer.nextMsg());
System.out.println("Received Response("+encodeMsg.length+" bytes)");
System.out.println(msg);
System.out.println("++++++++++++++++++++++++++++++++++++++");
System.out.println("");
/*
// 第二次发起投票
msg.setResponse(false);
encodeMsg = coder.toWire(msg);
System.out.println("Second Sending Inquery("+encodeMsg.length+" bytes)");
framer.frameMsg(encodeMsg, out);
System.out.println(msg);
System.out.println("++++++++++++++++++++++++++++++++++++++");
// 第二次接收投票返回
msg = coder.fromWire(framer.nextMsg());
System.out.println("Second Received Response("+encodeMsg.length+" bytes)");
System.out.println(msg);
System.out.println("++++++++++++++++++++++++++++++++++++++");
*/
socket.close();
}
}
服务器端
package com.suifeng.tcpip.chapter3.vote;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import com.suifeng.tcpip.chapter3.framer.Framer;
import com.suifeng.tcpip.chapter3.framer.LengthFramer;
public class VoteTCPBinaryServer
{
public static void main(String[] args) throws IOException
{
if(args.length != 1)
{
throw new IllegalArgumentException("Parameter:<Port>");
}
// 获取服务器的端口
int serverPort = Integer.parseInt(args[0]);
// 创建用于客户端连接的SocketServer实例
ServerSocket server = new ServerSocket(serverPort);
System.out.println("Server has started!!!!");
VoteMsgCoder coder = new VoteMsgBinaryCoder();
VoteService service = new VoteService();
while(true)
{
Socket socket = server.accept();
System.out.println("Handling client at "+socket.getRemoteSocketAddress());
Framer framer = new LengthFramer(socket.getInputStream());
byte[] req;
while((req = framer.nextMsg()) != null)
{
System.out.println("++++++++++++++++++++++++++++++++");
System.out.println("Received message("+req.length+")byte.");
// 先解码投票信息,再进行处理
VoteMsg resMsg = service.handleRequest(coder.fromWire(req));
// 对投票信息编码后返回
framer.frameMsg(coder.toWire(resMsg), socket.getOutputStream());
System.out.println("Resonpnse message:"+resMsg);
System.out.println("++++++++++++++++++++++++++++++++");
System.out.println("");
}
socket.close();
}
}
}
启动服务器端,监听39393端口

启动客户端
查看服务器端
再次启动客户端
再次查看服务器端