Java中writeUTF和readUTF的意外值
我有一个服务器在监听两个不同的端口,在接受连接后,它将客户机-套接字的组合名保存到一个hashMap中。 之后,它在循环中启动一个方法来检查哪个客户端正在发送消息以及谁是该消息的接收者,然后从哈希映射中检索套接字值并使用它初始化到该套接字的DataOutputStream 问题是服务器只接收前两条消息,并且它们包含奇怪的值。例如,客户端1向服务器写入(1),但在另一端接收到明显的随机值 发送数据的类是:Java中writeUTF和readUTF的意外值,java,sockets,server,dataoutputstream,Java,Sockets,Server,Dataoutputstream,我有一个服务器在监听两个不同的端口,在接受连接后,它将客户机-套接字的组合名保存到一个hashMap中。 之后,它在循环中启动一个方法来检查哪个客户端正在发送消息以及谁是该消息的接收者,然后从哈希映射中检索套接字值并使用它初始化到该套接字的DataOutputStream 问题是服务器只接收前两条消息,并且它们包含奇怪的值。例如,客户端1向服务器写入(1),但在另一端接收到明显的随机值 发送数据的类是: public class Game { List <Player> playe
public class Game {
List <Player> players = new ArrayList<Player>();
int size;
public Game() {
(...game code here...)
public void sendUpdatedTableValues(int nP, int nF, int nS, int sc)
{
/* string,byte,stringa,primitivo del messaggio
string - mittente; byte - tipo di messaggio; stringa - ricevente; prim - messaggio
*/
try {
DataOutputStream dataOut = new DataOutputStream(Lane.socket.getOutputStream());
dataOut.writeUTF("Pista " + Lane.laneNum);
dataOut.writeInt(1);
dataOut.writeUTF("Amministrazione");
dataOut.writeInt(nP);
dataOut.writeUTF("-");
dataOut.writeInt(nF);
dataOut.writeUTF("-");
dataOut.writeInt(nS);
dataOut.writeUTF("-");
dataOut.writeInt(sc);
dataOut.flush();
} catch (IOException ex) {
Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* This method send the player's number of strikes
* this method has ID byte = 3
* @param nP - Player Number
* @param nS - Strike Number
*/
public void sendStrikeCounter(int nP, int nS)
{
try {
DataOutputStream dataOut = new DataOutputStream(Lane.socket.getOutputStream());
dataOut.writeUTF("Pista " + Lane.laneNum);
dataOut.writeInt(3);
dataOut.writeUTF("Amministrazione");
dataOut.writeInt(nP);
dataOut.writeUTF("-");
dataOut.writeInt(nS);
dataOut.flush();
} catch (IOException ex) {
Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* This method updates result table on server
* this method has ID byte= 4
* @param nP - Player Number
* @param nF - Frame Number
* @param res - Frame result
*/
public void sendUpdatedResultsTable(int nP, int nF, int res)
{
try {
DataOutputStream dataOut = new DataOutputStream(Lane.socket.getOutputStream());
dataOut.writeUTF("Pista " + Lane.laneNum);
dataOut.writeInt(4);
dataOut.writeUTF("Amministrazione");
dataOut.writeInt(nP);
dataOut.writeUTF("-");
dataOut.writeInt(nF);
dataOut.writeUTF("-");
dataOut.writeInt(res);
dataOut.flush();
} catch (IOException ex) {
Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* This method send the player's number of spares
* this method has ID byte = 5
* @param nP - Player Number
* @param nS - Spare Number
*/
public void sendSpareCounter(int nP, int nS)
{
try {
DataOutputStream dataOut = new DataOutputStream(Lane.socket.getOutputStream());
dataOut.writeUTF("Pista " + Lane.laneNum);
dataOut.writeInt(5);
dataOut.writeUTF("Amministrazione");
dataOut.writeInt(nP);
dataOut.writeUTF("-");
dataOut.writeInt(nS);
dataOut.flush();
} catch (IOException ex) {
Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
}
}
公共类游戏{
List players=new ArrayList();
整数大小;
公共游戏(){
(…这里是游戏代码…)
public void sendUpdateTableValues(int-nP、int-nF、int-nS、int-sc)
{
/*字符串,字节,字符串,原始数据包
string-mittente;byte-tipo-di-messaggio;stringa-ricevent;prim-messaggio
*/
试一试{
DataOutputStream dataOut=新的DataOutputStream(Lane.socket.getOutputStream());
dataOut.writeUTF(“Pista”+laneNum);
dataOut.writeInt(1);
dataOut.writeUTF(“Amministrazione”);
dataOut.writeInt(nP);
dataOut.writeUTF(“-”);
dataOut.writeInt(nF);
dataOut.writeUTF(“-”);
dataOut.writeInt(nS);
dataOut.writeUTF(“-”);
数据输出写入(sc);
dataOut.flush();
}捕获(IOEX异常){
Logger.getLogger(Game.class.getName()).log(Level.SEVERE,null,ex);
}
}
/**
*此方法发送玩家的击数
*此方法的ID字节为3
*@param nP-玩家编号
*@param nS-罢工编号
*/
公共无效发送删除计数器(int nP,int nS)
{
试试{
DataOutputStream dataOut=新的DataOutputStream(Lane.socket.getOutputStream());
dataOut.writeUTF(“Pista”+laneNum);
数据输出写入(3);
dataOut.writeUTF(“Amministrazione”);
dataOut.writeInt(nP);
dataOut.writeUTF(“-”);
dataOut.writeInt(nS);
dataOut.flush();
}捕获(IOEX异常){
Logger.getLogger(Game.class.getName()).log(Level.SEVERE,null,ex);
}
}
/**
*此方法更新服务器上的结果表
*此方法的ID字节为4
*@param nP-玩家编号
*@param nF-帧编号
*@param res-帧结果
*/
public void sendUpdatedResultsTable(int-nP、int-nF、int-res)
{
试试{
DataOutputStream dataOut=新的DataOutputStream(Lane.socket.getOutputStream());
dataOut.writeUTF(“Pista”+laneNum);
数据输出写入(4);
dataOut.writeUTF(“Amministrazione”);
dataOut.writeInt(nP);
dataOut.writeUTF(“-”);
dataOut.writeInt(nF);
dataOut.writeUTF(“-”);
数据输出写入(res);
dataOut.flush();
}捕获(IOEX异常){
Logger.getLogger(Game.class.getName()).log(Level.SEVERE,null,ex);
}
}
/**
*此方法发送玩家的备用数量
*此方法的ID字节为5
*@param nP-玩家编号
*@param nS-备用编号
*/
public void sendsparecocounter(int-nP,int-nS)
{
试试{
DataOutputStream dataOut=新的DataOutputStream(Lane.socket.getOutputStream());
dataOut.writeUTF(“Pista”+laneNum);
数据输出写入(5);
dataOut.writeUTF(“Amministrazione”);
dataOut.writeInt(nP);
dataOut.writeUTF(“-”);
dataOut.writeInt(nS);
dataOut.flush();
}捕获(IOEX异常){
Logger.getLogger(Game.class.getName()).log(Level.SEVERE,null,ex);
}
}
服务器的代码为:
public class Server {
public static List <Player> players = new ArrayList <Player> ();
public static HashMap <String, List<Player>> laneHashMap = new HashMap<String, List<Player>>();
ServerSocket adminListener;
ServerSocket clientListener;
public static void main(String[] args) throws IOException {
System.out.println("Server bowling avviato:\n");
Server server = new Server();
/**
* The port 9090 is reserved for the admin client, the other port is
* used by all the lane clients
*/
server.adminListener = new ServerSocket(9090);
server.clientListener = new ServerSocket(9898);
int clientNumber = 1; //Used to keep track of every single lane
//Create an HashMap used to store the name and the socket of the clients
HashMap<String, Socket> socketMap = new HashMap<>();
/**
* The server starts two different threads that keep listening for
* incoming connections
*/
new threadAdminPort(server.adminListener, socketMap).start();
new threadClientPort(server.clientListener, socketMap, clientNumber).start();
}
/**
* Used to listen to port 9090
*/
private static class threadAdminPort extends Thread {
private ServerSocket adminListener;
private HashMap<String, Socket> socketMap;
public threadAdminPort(ServerSocket adminListener, HashMap<String, Socket> socketMap) {
this.adminListener = adminListener;
this.socketMap = socketMap;
}
@Override
public void run() {
try {
while (true) {
new Handler(adminListener.accept() , socketMap).start();
}
} catch (IOException e) {
System.out.println("Errore di accept: " + e);
} finally {
try {
adminListener.close();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
/**
* Used to listen to port 9898
*/
private static class threadClientPort extends Thread {
private ServerSocket clientListener;
private HashMap<String, Socket> socketMap;
private int clientNumber;
public threadClientPort(ServerSocket clientListener , HashMap<String, Socket> socketMap , int clientNumber) {
this.clientListener = clientListener;
this.socketMap = socketMap;
this.clientNumber = clientNumber;
}
@Override
public void run() {
try {
while (true) {
new Handler(clientListener.accept() , socketMap , clientNumber++).start();
}
} catch (IOException e) {
System.out.println("Errore di accept: " + e);
} finally {
try {
clientListener.close();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
/**
* A private thread to handle requests on a particular socket.
*/
private static class Handler extends Thread {
Socket socket;
HashMap<String, Socket> socketMap;
int clientNumber;
//Set true only if it is received a endOfGame message
boolean endOfGame = false;
/**
* This constructor is meant to be used by the lane clients.
*/
public Handler(Socket socket, HashMap<String, Socket> socketMap , int clientNumber) throws IOException {
this.socket = socket;
this.socketMap = socketMap;
this.clientNumber = clientNumber;
String clientName = "Pista " + clientNumber;
synchronized(socketMap) {
socketMap.put(clientName, socket);
}
//Send laneNum to the client
DataOutputStream dataOut = new DataOutputStream(socket.getOutputStream());
dataOut.writeInt(clientNumber);
System.out.println("- Pista " + clientNumber + " connessa -\nPronta per giocare");
}
/**
* This constructor is meant to be used by the admin client as it
* provides no clientNumber variable.
*/
public Handler(Socket socket , HashMap<String, Socket> socketMap) {
this.socket = socket;
this.socketMap = socketMap;
String clientName = "Amministrazione";
synchronized (socketMap) {
socketMap.put(clientName, socket);
}
System.out.println("- Client Amministrazione connesso -");
}
/**
* This function is shared by both the admin client and the lane clients
*/
@Override
public void run() {
forwardMessage();
try {
socket.close();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
if(clientNumber==0)
System.out.println("Connessione con il client amministrazione terminata");
else
System.out.println("Connessione con il client " + clientNumber + " terminata");
}
private void forwardMessage () {
Set set = socketMap.entrySet();
Iterator iterator = set.iterator();
//The following are the fixed fields of a message
String sender = null;
String receiver = null;
int messageType = 100;
//while(iterator.hasNext())
while(true){
for(Map.Entry<String, Socket> entry : socketMap.entrySet()){
// Map.Entry mapEntry = (Map.Entry)iterator.next();
Socket tempRecSocket = (Socket) entry.getValue();
System.out.println("Il valore di tempRecSocket è "+ tempRecSocket);
DataInputStream dataIn;
DataOutputStream dataOut;
try {
dataIn = new DataInputStream(tempRecSocket.getInputStream());
//Analyze and understand what type of message it is and who is
//the sender and the receiver
sender = dataIn.readUTF();
messageType = dataIn.readInt();
System.out.println("Sender ricevuto "+ sender);
receiver = dataIn.readUTF();
System.out.println("Receiver ricevuto " + receiver);
switch (messageType) {
case 0:
{
//player 1
boolean start = dataIn.readBoolean();
String namezero = dataIn.readUTF();
int shoeszero = dataIn.readInt();
String cf = dataIn.readUTF();
//player 2
int shoesone = dataIn.readInt();
String nameone = dataIn.readUTF();
//player 3
int shoestwo = dataIn.readInt();
String nametwo = dataIn.readUTF();
//player 4
int shoesthree = dataIn.readInt();
String namethree = dataIn.readUTF();
//player 5
int shoesfour = dataIn.readInt();
String namefour = dataIn.readUTF();
//player 6
int shoesfive = dataIn.readInt();
String namefive = dataIn.readUTF();
laneHashMap.put(receiver, players); //insert in hashmap lane data
laneHashMap.get(receiver).add(new Player(0,namezero,shoeszero,cf)); //add player0 in players list7
laneHashMap.get(receiver).add(new Player(1,shoesone,nameone));
laneHashMap.get(receiver).add(new Player(2,shoestwo,nametwo));
laneHashMap.get(receiver).add(new Player(3,shoesthree,namethree));
laneHashMap.get(receiver).add(new Player(4,shoesfour,namefour));
laneHashMap.get(receiver).add(new Player(5,shoesfive,namefive));
Socket tempSndSocket = (Socket) socketMap.get(receiver);
System.out.println("Il valore di tempSndSocket è "+ tempSndSocket);
dataOut = new DataOutputStream(tempSndSocket.getOutputStream());
dataOut.writeUTF(sender);
dataOut.writeInt(messageType);
if(messageType!=0)
System.out.println("Valore di messageType "+ messageType);
dataOut.writeUTF(receiver);
dataOut.writeBoolean(start);
for (int i = 0;i<6;i++)
{
laneHashMap.get(receiver).get(i).setInitialTable();
dataOut.writeUTF(laneHashMap.get(receiver).get(i).getName());
dataOut.writeInt(0); //separatore
} dataOut.flush();
// dataOut.close();
System.out.println("Il server ha inviato correttamente il messaggio di tipo 0");
break;
}
case 1:
{
System.out.println("Il server ha ricevuto correttamente il messaggio di tipo 1 ed ora provvederà all'invio");
//sendUpdatedTableValues
int playerNumber = dataIn.readInt();
dataIn.readUTF();
int frameNumber = dataIn.readInt();
dataIn.readUTF();
int shotNumber = dataIn.readInt();
dataIn.readUTF();
int score = dataIn.readInt();
System.out.println("Ho ricevuto: 1 - "+ playerNumber + "2 - framenumber "+ frameNumber+ "3 - shotNumber" + shotNumber+ "4 - score "+ score);
//update local player data
laneHashMap.get(sender).get(playerNumber).setTable(frameNumber, shotNumber, score);
System.out.println("In questo turno il giocatore ha totalizzato "+ laneHashMap.get(sender).get(playerNumber).getTable(frameNumber, shotNumber));
Socket tempSndSocket = (Socket) socketMap.get(receiver);
dataOut = new DataOutputStream(tempSndSocket.getOutputStream());
dataOut.writeUTF(sender);
dataOut.writeInt(messageType);
dataOut.writeUTF(receiver);
dataOut.writeInt(playerNumber);
dataOut.writeUTF("-");
dataOut.writeInt(frameNumber);
dataOut.writeUTF("-");
dataOut.writeInt(shotNumber);
dataOut.writeUTF("-");
dataOut.writeInt(score);
break;
}
break;
}
公共类服务器{
publicstaticlist-players=newarraylist();
public static HashMap laneHashMap=new HashMap();
ServerSocket管理员监听器;
ServerSocket客户端监听器;
公共静态void main(字符串[]args)引发IOException{
System.out.println(“服务器bowling avviato:\n”);
服务器=新服务器();
/**
*端口9090是为管理客户端保留的,另一个端口是
*被所有的客户端使用
*/
server.adminListener=newserversocket(9090);
server.clientListener=newserversocket(9898);
int clientNumber=1;//用于跟踪每条车道
//创建一个HashMap,用于存储客户端的名称和套接字
HashMap socketMap=新HashMap();
/**
*服务器启动两个不同的线程,继续侦听
*传入连接
*/
新的threadAdminPort(server.adminListener,socketMap).start();
新的threadClientPort(server.clientListener,socketMap,clientNumber).start();
}
/**
*用于侦听端口9090
*/
私有静态类threadAdminPort扩展线程{
私有服务器套接字管理员侦听器;
私有HashMap-socketMap;
公共线程AdminPort(ServerSocket adminListener、HashMap socketMap){
this.adminListener=adminListener;
this.socketMap=socketMap;
}
@凌驾
公开募捐{
试一试{
while(true){
新处理程序(adminListener.accept(),socketMap.start();
}
}捕获(IOE异常){
System.out.println(“错误di接受:+e”);
}最后{
试一试{
adminListener.close();
}捕获(IOEX异常){
Logger.getLogger(Server.class.getName()).log(Level.SEVERE,null,ex);
}
}
}
}
/**
*用于侦听端口9898
*/
私有静态类threadClientPort扩展线程{
私有服务器套接字clientListener;
私有HashMap-socketMap;
私人int客户号;
公共threadClientPort(ServerSocket clientListener、HashMap socketMap、int clientNumber){
this.clientListener=clientListener;
this.socketMap=socketMap;
this.clientNumber=clientNumber;
}
@凌驾
公共vo