Java Server, Unity C# Client Are Freezing - java

I am building a Sphinx4 Java Server where Unity3D should communicate with. Sending audio data from Unity C# to the Java server works fine. Speech recognition with the received data works fine too. The problem appears when I try to send data from Java back to C#.
My current code:
JAVA
package main;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import edu.cmu.sphinx.api.Configuration;
import edu.cmu.sphinx.api.SpeechResult;
import edu.cmu.sphinx.api.StreamSpeechRecognizer;
public class SpeechRecognition {
private static StreamSpeechRecognizer recognizer;
private static Configuration configuration;
public static void main(String[] args) {
configuration = new Configuration();
configuration.setAcousticModelPath("resource:/edu/cmu/sphinx/models/en-us/en-us");
configuration.setDictionaryPath("resource:/edu/cmu/sphinx/models/en-us/cmudict-en-us.dict");
configuration.setLanguageModelPath("resource:/edu/cmu/sphinx/models/en-us/en-us.lm.bin");
try {
recognizer = new StreamSpeechRecognizer(configuration);
ServerSocket serverSocket = new ServerSocket(82);
while (System.in.available() == 0) {
Socket socket = serverSocket.accept();
System.out.println("Client found");
String recognized = RecognizeText(socket.getInputStream());
System.out.println("sending now");
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
String json = recognized;
out.print(json);
out.flush();
out.close();
socket.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Quitting...");
serverSocket.close();
}
private static String RecognizeText(InputStream stream) throws Exception {
recognizer.startRecognition(stream);
SpeechResult result;
String resultString="";
while ((result = recognizer.getResult()) != null) {
resultString = result.getHypothesis();
System.out.format("Hypothesis: %s\n", resultString);
}
recognizer.stopRecognition();
return resultString;
}
}
Now my C# code is like this:
void Start () {
dataPath = Application.dataPath;
t = new Thread(Client);
t.Start();
}
private void Client()
{
String input;
TcpClient tcpClient = new TcpClient("localhost", 82);
NetworkStream networkStream = tcpClient.GetStream();
BinaryWriter bw = new BinaryWriter(networkStream);
var filepath = dataPath + "/Resources/audio/test.wav";
FileStream filestream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
BinaryReader filereader = new BinaryReader(filestream);
byte[] bytes = filereader.ReadBytes((Int32)filestream.Length);
bw.Write(bytes);
bw.Flush();
StreamReader streamReader = new StreamReader(networkStream);
input = streamReader.ReadToEnd();
print("Received data: " + input + "\n");
}
The recognition takes around 10 seconds. When te result is given the system freezes.
The Println("sending now") (in Java) is not printed. So it freezes before it even reaches it.
The weird thing is: When I only send text from Java to C# or from C# to Java, it works. If I want to send and receive on both ends, it freezes. And I need to send and receive data at the same time

I have found the anwser:
The loop is not broken in RecognizeText, placing the return statement within the while loop fixes the issue, as the recognized text will be returned first anyway.

Related

Cannot read objects of two classes from stream

Good afternoon! I am writing a program that generates random parameters for a circle and a rectangle on the server. The data is formed correctly and is written correctly to the ObjectOutputStream on the server. After I want to read this data in the client, first I read the data for the circle (they come and output correctly, but after the circle the rectangle data is read. Everything seemed to be going well, but an exception occurred on the ObjectInputStream line java.io.StreamCorruptedException: invalid stream header: 7372000F.
Here is the server code
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
public class Server {
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(8000);
Socket socket = ss.accept();
OutputStream os = socket.getOutputStream();
CircleParams []cp = new CircleParams[3];
for(int i=0;i<cp.length;i++)
{
cp[i] = new CircleParams();
System.out.println(cp[i]);
}
RectangleParams rp = new RectangleParams();
System.out.println(rp);
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream objStream = new ObjectOutputStream(byteStream);
objStream.writeObject(cp);
byte[] circle = byteStream.toByteArray();
byte[] lengthCircle = ByteBuffer.allocate(4).putInt(circle.length).array();
os.write(lengthCircle);
os.write(circle);
objStream.reset();
byteStream.reset();
objStream.writeObject(rp);
byte[] rects = byteStream.toByteArray();//Rectangle
byte[] lengthRect = ByteBuffer.allocate(4).putInt(rects.length).array();
os.write(lengthRect);
os.write(rects);
os.write(35343);
os.flush();
objStream.flush();
byteStream.close();
objStream.close();
os.close();
ss.close();
socket.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
And accordingly the client code
import java.io.*;
import java.net.Socket;
import java.nio.ByteBuffer;
public class Client {
public static void main(String[] args) {
try {
Socket s = new Socket("192.168.4.101", 8000);
InputStream is = s.getInputStream();
while (s != null && s.isConnected()) {
try {
byte[] lenghtMas = new byte[4];
is.read(lenghtMas);
int n = ByteBuffer.wrap(lenghtMas).asIntBuffer().get();
if (n > 0) {
byte[] message = new byte[n];
is.read(message);
ByteArrayInputStream bais = new ByteArrayInputStream(message);
ObjectInputStream ois = new ObjectInputStream(bais);
CircleParams[] cp = (CircleParams[]) ois.readObject();
for (int i = 0; i < cp.length; i++) {
System.out.println(cp[i]);
}
}
byte[] lenghtRect = new byte[4];
is.read(lenghtRect);
int m = ByteBuffer.wrap(lenghtRect).asIntBuffer().get();
if(m>0){
byte[] rect = new byte[m];
is.read(rect);
ByteArrayInputStream bais = new ByteArrayInputStream(rect);
ObjectInputStream ois = new ObjectInputStream(bais);
RectangleParams rp = (RectangleParams) ois.readObject();
System.out.println(rp);
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
s.close();
is.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
And in the fields of the class, I registered two commands
for RectangleParams: private static final long serialVersionUID = 685098267757690L;
For CircleParams: private static final long serialVersionUID = 6529685098267757690L;
These fields are present in the server and client classes. The shape classes of the server and the client are the same.
How can I get rid of the error and receive the data correctly?
I checked all the code line by line in the debug. And I noticed that for RectangleParams the length of the byte array is transmitted correctly, but the array itself is incorrect. I also took advice from the Internet and assigned a variable of type int, reading an array from a stream. and I saw that there -1.
In the client, I expect to see data for building a circle, and data for building a rectangle. But now I see only the data for the circle, and below the exception text

Java ServerSocket is not sending Data Back to Client

so im currently working on an minecraft plugin which you can ignore in this case since im pretty sure its just the ServerSocket. So the thing is after all the code the http server is executed successfully the sender should recieve a simple OK from the server. But in this case nothing happens. And when i add out.close() almost at the end ill just get an "socket hung up" in postman. Im pretty sure this issue comes from me being a big stupid and having no idea how to use ServerSockets in Java. Its important to know that the data actually arrives and can be parsed from an json successfully. Thanks in advance :)
Heres the code:
package com.lam;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.io.*;
import java.net.*;
import com.google.gson.*;
import org.bukkit.inventory.ItemStack;
import org.bukkit.Material;
public class BukkitHTTPWorker extends BukkitRunnable {
static final int port = 8080;
static final String newLine = "\r\n";
private final JavaPlugin plugin;
public BukkitHTTPWorker(JavaPlugin plugin){
this.plugin = plugin;
}
#Override
public void run(){
try {
ServerSocket socket = new ServerSocket(port);
while (true) {
Socket connection = socket.accept();
try {
BufferedReader in=new BufferedReader(new InputStreamReader(connection.getInputStream()));
BufferedWriter out=new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
String request = in.readLine();
if (request == null) continue;
StringBuilder payload = new StringBuilder();
while(in.ready()){
payload.append((char) in.read());
}
String body = payload.toString();
String jsonString = body.substring(body.indexOf("{"));
System.out.println(jsonString);
JsonObject rootObj = JsonParser.parseString(jsonString).getAsJsonObject();
JsonArray itemsArray = rootObj.getAsJsonArray("items");
String username = rootObj.get("username").getAsString();
try {
Player player = Bukkit.getPlayer(username);
for (JsonElement ia : itemsArray){
JsonObject itemObj = ia.getAsJsonObject();
System.out.println(itemObj.get("id").getAsString());
System.out.println(itemObj.get("amount").getAsString());
Material mat = Material.getMaterial(itemObj.get("id").getAsString());
if (mat != null && player != null){
ItemStack item = new ItemStack(mat);
item.setAmount(itemObj.get("amount").getAsInt());
player.getInventory().addItem(item);
String httpResponseOK = "HTTP/1.0 200 OK\r\n\r\n";
out.write(httpResponseOK);
} else {
System.err.println("Error occured on ItemHTTP");
}
}
} catch (Throwable tris){
System.err.println("Error giving Items to Player" + tris);
}
} catch (Throwable tri){
System.err.println("Internal HTTP Server Error... " + tri);
socket.close();
}
}
} catch (Throwable tr) {
System.err.println("Could not init server... " + tr);
}
}
}

Java gui, Client issue when trying to convert into gui

I have made a Client/Server programme in java, I have gotten it to work using the cmd perfectly as i want, now i am trying to convert the client side of the code into GUI, however i am having trouble with printing the client msg and reading the client input from the text fields and the server msg, here is what I have done so far, i get no errors when compiling but the gui it self doesn't run, any help is appreciated.
Here is the Client code:
import java.net.*;
import java.io.*;
import java.awt.*;
import java.util.Scanner;
import javax.swing.*;
public class TcpClient
{
public static void main(String[] args)
{
try
{
new TcpClient().start();
}
catch(Exception e)
{
System.out.println("Major Error" + e.getMessage());
e.printStackTrace();
}
}
public void start() throws IOException
{
JFrame build = new JFrame("Client");
JTextField serv = new JTextField();
JTextField clie = new JTextField();
build.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
serv.setBounds(50,210,300,50);
build.add(serv);
clie.setBounds(350,210,300,50);
build.add(clie);
//=====================================================================
Socket clientSocket = null;
InetAddress hostA = null;
PrintWriter clientOutput = null;
BufferedReader clientInput = null;
BufferedReader standardInput = null;
try
{
hostA = InetAddress.getLocalHost();
clientSocket = new Socket(hostA.getHostName(), 5600);
clientInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
clientOutput = new PrintWriter(clientSocket.getOutputStream(), true);
standardInput = new BufferedReader(new InputStreamReader(System.in));
String serverMsg, clientMsg;
//read from a socket and respond back to server
while((serverMsg = clientInput.readLine()) != null)
{
serv.setText("Server Saying - " + serverMsg);
if(serverMsg.equals("exit"))
break;
clientMsg = standardInput.readLine();
if(clientMsg != null)
{
clie.setText("Client Saying - " + clientMsg);
clientOutput.println(clientMsg);
}
}
}
catch(UnknownHostException e)
{
System.exit(1);
}
catch(IOException e)
{
System.exit(1);
}
finally
{
//clean up time
clientOutput.close();
clientInput.close();
standardInput.close();
clientSocket.close();
}
//=====================================================================
build.setLayout(null);
build.setSize(700,600);
build.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
build.setVisible(true);
build.setResizable(false);
}
}
As mentioned in the comments you should study multithreading and especially the EDT
What is happening right now is that your code and your GUI and preventing each other from working properly. By having your GUI run on the EDT your application can run without holding back the GUI. When the application has changes to report that are relevant for your GUI you can just inform the EDT when the time comes.

Java Sockets: My server input stream will not read from the client output stream?

EDIT: Ik it is long but does anyone know how to program sockets??
My problem is confusing me a bit. I have a server running on one computer and on another, I have a client connected to it. When I type a message from the client into the console and send it, the server does not seem to receive it. Anybody know why because I have been testing with printing to the console for the last 3 hours and cannot figure this out. I am relatively new to sockets so don't be too harsh if I am just being an idiot.
Heres my code for the client side:
import java.net.*;
import java.util.Scanner;
import java.io.*;
public class SocketClient {
public static void main(String [] args) {
String host = "************";
int port = 25565;
StringBuffer instr = new StringBuffer();
String TimeStamp;
System.out.println("SocketClient initialized");
try {
InetAddress address = InetAddress.getByName(host);
Socket connection = new Socket(address, port);
BufferedOutputStream bos = new BufferedOutputStream(connection.getOutputStream());
OutputStreamWriter osw = new OutputStreamWriter(bos, "US-ASCII");
Scanner scan = new Scanner(System.in);
String message = scan.nextLine();
TimeStamp = new java.util.Date().toString();
String process = "Server called on " + host + ":" + port + " at " + TimeStamp + ": " + message + (char) 13;
osw.write(process);
osw.flush();
BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
InputStreamReader isr = new InputStreamReader(bis, "US-ASCII");
int c;
while ( (c = isr.read()) != 13)
instr.append( (char) c);
connection.close();
System.out.println(instr);
} catch (UnknownHostException e) {
System.err.println("UnknownHostException: " + e);
} catch (IOException e) {
System.err.println("IOExcepion: " + e);
}
}
}
Here is the code to connect the client to the server:
import java.io.IOException;
import java.net.*;
public class MultipleSocketServer {
public static Socket connection;
public static String name = "Tyler's Server";
public static int limit = 2;
public static Thread[] clients = new Thread[limit];
public static int current = 0;
public static int port = 25565;
public static String[] connected = {"", ""};
public static ServerSocket socket;
public static void main(String[] args) {
System.out.println("Server starting...");
try {
ServerSocket socket = new ServerSocket(port);
while(true) {
Socket connection = socket.accept();
String ip = connection.getRemoteSocketAddress().toString().substring(1, 13);
loop:
for(int i = 0; i < connected.length; i++) {
if(connected[0].equals(ip) || connected[1].equals(ip)) {
break loop;
}else if(!connected[i].equals(ip)) {
connected[i] = ip;
System.out.println(ip);
MultiServer_Client client = new MultiServer_Client(connection, i);
Thread run = new Thread(client);
run.start();
break loop;
}
}
}
} catch (IOException e1) {
System.out.println("Could not bind server on: " + port);
System.exit(-1);
}
}
}
And here is my code to handle each client as connected:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class MultiServer_Client implements Runnable {
public String time;
public Socket client;
public StringBuffer process = new StringBuffer();
public BufferedInputStream inputStream;
public InputStreamReader reader;
public BufferedOutputStream outputStream;
public OutputStreamWriter writer;
public boolean connected = true;
public int ID;
public MultiServer_Client(Socket connection, int i) {
client = connection;
ID = i;
try {
inputStream = new BufferedInputStream(client.getInputStream());
reader = new InputStreamReader(inputStream);
outputStream = new BufferedOutputStream(client.getOutputStream());
writer = new OutputStreamWriter(outputStream, "US-ASCII");
} catch (IOException e) {
System.out.println("IOException: " + e);
}
System.out.println("Client connected...");
write("Connected to " + MultipleSocketServer.name);
}
public void run() {
while(connected) {
write("hi");
}
System.out.println("Disconnecting client...");
}
public void write(String authen) {
try {
time = new java.util.Date().toString();
String message = time + ": " + authen + (char) 13;
writer.write(message);
writer.flush();
} catch (IOException e) {
connected = false;
MultipleSocketServer.connected[ID] = "";
}
}
public void read() {
//read from client
int character;
process = new StringBuffer();
try {
while ((character = reader.read()) != 13) {
process.append((char) character);
}
System.out.println(process);
process.delete(0, process.length());
} catch (IOException e) {
connected = false;
MultipleSocketServer.connected[ID] = "";
}
}
}
Srry if I cannot help very much. As I said, I am new to sockets and no one else seems to have any problems with this... Thanks :)
The problem with your code is not the "sockets" its your communication protocol. You are effectively closing the socket before the server has a chance to write out "hi".
To debug this, you want to reduce the complexity of your program. There are a number of things that don't make any sense or matter in your program.
So, a little background on Sockets. There are two types of sockets. A "ServerSocket" and a "Socket" The ServerSocket is sort of like a secretary. Its only job is to listen for calls and then pass them on. This is what the "accept" does. Before any client connects, the accept() will block until it receives a connection. Once the client connects, the accept returns a Socket representing the connection.
The regular Socket is where all the work occurs. You can think of it as a telephone connection. You can talk to someone remotely with the OutputStream, and listen using the InputStream. The challenge is that you need to create some sort of communication (called a protocol) for your two sockets to communicate.
You need to figure out how you want to delimit your commands. You could pass a fixed length number and then the data if you want a "length" delimited protocol or you could use a special character for the end of the message (what you currently have). For the quick and dirty, I often use the latter with a newline character. The easiest is to just use a PrintWriter for writing and a Scanner for reading.
The next step is to figure out the communication pattern for the client and the server. Think if it as passing a ball back and forth. If the client says something, the other side should be listening (and vice versa).
Once the protocol and logic is figured out, you can then move the logic for "handling" the server side into separate threads (called a worker pattern) so that the server can handle more than one client at a time. If you want to go even further, you can implement a reactor with a thread pool so that the server doesn't run out of threads, but that is probably for another day/question.
I would recommend following the Java tutorial on Sockets: http://docs.oracle.com/javase/tutorial/networking/sockets/index.html

http server and client implementing head and get method

I'm trying to make a simple http client server using java. It will show the client's request as well as the server's response. For example server will send back
HTTP/1.0 200 OK
Connection: Close. etc.
Previously i had a echo client server. Now I've turned my echo server to act as a http server. I've tried Goggling about how to implement the head and get with the client but i noticed usually all of the example used apache framework. Is there a way to implement these method without apache framework.
My echo client which i'm trying to convert into a http client:
import java.io.*;
import java.net.*;
public class Ec1
{
public static void main(String[] args)
{
try
{
Socket s = new Socket("127.0.0.1", 80);
BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter w = new PrintWriter(s.getOutputStream(), true);
BufferedReader con = new BufferedReader(new InputStreamReader(System.in));
String line;
do
{
line = r.readLine();
if ( line != null )
System.out.println(line);
line = con.readLine();
w.println(line);
}
while ( !line.trim().equals("bye") );
}
catch (Exception err)
{
System.err.println(err);
}
}
}
My Http server:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Echo
{
protected void start() {
ServerSocket s;
System.out.println("Webserver starting up on port 80");
try {
// create the main server socket
s = new ServerSocket(80);
} catch (Exception e) {
System.out.println("Error: " + e);
return;
}
Socket clientSocket = null;
System.out.println ("Waiting for connection.....");
try {
clientSocket = s.accept();
System.out.println("Connection, sending data.");
BufferedReader in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
String str = ".";
while (!str.equals(""))
str = in.readLine();
out.println("HTTP/1.0 200 OK");
out.println("Content-Type: text/html");
out.println("Server: Bot");
out.println("");
out.println("<H1>Welcome to the Ultra Mini-WebServer</H2>");
out.flush();
clientSocket.close();
s.close();
} catch (Exception e) {
System.out.println("Error: " + e);
}
}
public static void main(String args[]) {
WebServer ws = new WebServer();
ws.start();
}
}
Yes, there is, just interpret your request you're getting from the client.
From the following code (in HttpServer), parse:
String str = ".";
while (!str.equals("")) {
str = in.readLine();
if (str.startsWith("HEAD")) {
//Head execution here...
}
}
Etc...
Everybody uses some kind of library or framework for the client and/or the server side because HTTP is somewhat complex and there is no need to reinvent every wheel. However, it is quite possible to write your own implementation by starting directly from the RFCs for HTTP.

Categories