Я новичок в Java NIO и хочу создать программу, которая позволит пользователю вводить код продукта и его количество и отправлять на сервер. Затем сервер обработает цену товара и отправит цену клиенту. На стороне клиента будет отображаться цена товара
public class NIOProductServer {
private Selector selector;
private InetSocketAddress listenAddress;
private final static int PORT = 9093;
ArrayList<Product> products=new ArrayList<Product>();
ArrayList<Integer> orderedItems=new ArrayList<Integer>();
public static void main(String[] args) throws Exception {
try {
new NIOProductServer("localhost", 9093).startServer();
} catch (IOException e) {
e.printStackTrace();
}
}
public NIOProductServer(String address, int port) throws IOException {
listenAddress = new InetSocketAddress(address, PORT);
// Initialize vairable and add to array list
Product product1=new Product();
Product product2=new Product();
Product product3=new Product();
product1.setName("Whopper");
product1.setPrice(11.95);
product1.setProductCode(101);
product2.setName("Whopper with Cheese");
product2.setPrice(14.15);
product2.setProductCode(102);
product3.setName("BK Double Mushroom Swiss");
product3.setPrice(11.45);
product3.setProductCode(103);
products.add(product1);
products.add(product2);
products.add(product3);
}
/**
* Start the server
*
* @throws IOException
*/
private void startServer() throws IOException {
this.selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
// bind server socket channel to port
serverChannel.socket().bind(listenAddress);
serverChannel.register(this.selector, SelectionKey.OP_ACCEPT);
System.out.println("Server started on port >> " + PORT);
while (true) {
// wait for events
int readyCount = selector.select();
if (readyCount == 0) {
continue;
}
// process selected keys...
Set<SelectionKey> readyKeys = selector.selectedKeys();
Iterator iterator = readyKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = (SelectionKey) iterator.next();
// Remove key from set so we don't process it twice
iterator.remove();
if (!key.isValid()) {
continue;
}
if (key.isAcceptable()) { // Accept client connections
this.accept(key);
} else if (key.isReadable()) { // Read from client
this.read(key);
} else if (key.isWritable()) { // write data to client...
this.write(key);
}
}
}
}
// accept client connection
private void accept(SelectionKey key) throws IOException {
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel channel = serverChannel.accept();
channel.configureBlocking(false);
Socket socket = channel.socket();
SocketAddress remoteAddr = socket.getRemoteSocketAddress();
System.out.println("Connected to: " + remoteAddr);
/*
* Register channel with selector for further IO (record it for read/write
* operations, here we have used read operation)
*/
channel.register(this.selector, SelectionKey.OP_READ);
}
// read from the socket channel
private void read(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int numRead = -1;
numRead = channel.read(buffer);
if (numRead == -1) {
Socket socket = channel.socket();
SocketAddress remoteAddr = socket.getRemoteSocketAddress();
System.out.println("Connection closed by client: " + remoteAddr);
channel.close();
key.cancel();
return;
}
byte[] data = new byte[numRead];
System.arraycopy(buffer.array(), 0, data, 0, numRead);
String got=new String(data);
System.out.println("Got: " + got);
// Separate the string and find variable
StringTokenizer tokenizer = new StringTokenizer(got, "\n");
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
StringTokenizer separator = new StringTokenizer(token, ":");
String label = separator.nextToken();
if (label.equalsIgnoreCase("Product Code")) {
orderedItems.add(Integer.parseInt(separator.nextToken()));
} else if (label.equalsIgnoreCase("Quantity")) {
orderedItems.add(Integer.parseInt(separator.nextToken()));
}
}
// Change the selector to write
channel.register(this.selector, SelectionKey.OP_WRITE);
}
private void write(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
double subtotal=0;
// This should print at client side
System.out.println("Code\tName\t\t\tPrice\tQuantity\tSub Total");
// loop to calculate product subtotal
for(int i=0;i<orderedItems.size();i+=2) {
for(Product p:products){
if(p.getProductCode()==orderedItems.get(i)){
subtotal+=p.getPrice()*orderedItems.get(i+1);
System.out.print(p.getProductCode()+"\t"+p.getName()+"\t"+p.getPrice()+"\t\t"+orderedItems.get(i+1)+"\t\t");
}
}
}
System.out.println(subtotal+"\n");
// remove unsed arraylist item
orderedItems.remove(1);
orderedItems.remove(0);
channel.register(this.selector, SelectionKey.OP_CONNECT);
}
}
/ **************************************************************************** /
public class NIOProductClient {
public void startClient() throws IOException, InterruptedException {
InetSocketAddress hostAddress = new InetSocketAddress("localhost", 9093);
SocketChannel client = SocketChannel.open(hostAddress);
System.out.println("Client... started");
OrderedItem orderedItem1=new OrderedItem();
// Get input from user and set into object
Scanner scanner = new Scanner(System.in);
System.out.println("\n\nEnter product code");
orderedItem1.setProductCode(scanner.nextInt());
System.out.println("Enter quantity");
orderedItem1.setQuantity(scanner.nextInt());
scanner.close();
// Send messages to server
String[] messages = new String[] { "Product Code:"+orderedItem1.getProductCode()+"\nQuantity:"+orderedItem1.getQuantity() };
for (int i = 0; i < messages.length; i++) {
ByteBuffer buffer = ByteBuffer.allocate(74);
buffer.put(messages[i].getBytes());
buffer.flip();
client.write(buffer);
System.out.println(messages[i]);
buffer.clear();
Thread.sleep(5000);
}
client.close();
}
public static void main(String[] args) {
Runnable client = new Runnable() {
@Override
public void run() {
try {
new NIOProductClient().startClient();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
new Thread(client, "client-A").start();
}
}
Все работает нормально, кроме функции записи на стороне сервера.
Клиент ожидал получить вывод, подобный этому
Код Имя Цена КоличествоИтого
103 BK Double Mushroom 11,45 2 22,9