I have implemented Socket for a multiplayer game using libGdx.
Client side
private void startClient(String ip, int port) {
SocketHints socketHints = new SocketHints();
// Socket will time our in 4 seconds
socketHints.connectTimeout = 4000;
//create the socket and connect to the server entered in the text box ( x.x.x.x format ) on port 9021
Socket socket = Gdx.net.newClientSocket(Net.Protocol.TCP, ip, port,
socketHints);
try {
System.out.println("JoinScreen.startClient");
// write our entered message to the stream
OutputStream out = socket.getOutputStream();
out.write("testtest shine \n".getBytes());
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
Server code
private void startThreadServer() {
new Thread(new Runnable() {
#Override
public void run() {
System.out.println("HotspotHomeScreen.run");
ServerSocketHints serverSocketHint = new ServerSocketHints();
serverSocketHint.acceptTimeout = 0;
ServerSocket serverSocket = Gdx.net.newServerSocket(Net.Protocol.TCP, mPort, serverSocketHint);
String messageStr = null;
while (true) {
// Create a socket
Socket socket = serverSocket.accept(null);
System.out.println("while true");
int value = 0;
BufferedReader buffer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
try {
while ((value = buffer.read()) != -1) {
char c = (char) value;
if (value != 0 && value != 155)
messageStr = messageStr + c;
// Read to the next newline (\n) and display that text on labelMessage
System.out.println("HotspotHomeScreen.run " + buffer.readLine());
System.out.println("test messageStr = " + messageStr);
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("testnjnihg test" + messageStr);
System.out.println("HostScreen last line");
}
}
}).start(); // And, start the thread running
}
The BufferedReader is invoked after starting the server on one device,but data cannot read. When I switch to debug mode, after reaching while ((value = buffer.read()) != -1) { the buffer shows all the data I sent in the debugger console,but the execution stops there. Sorry for my bad Language
Related
I want to make my android app open socket to my windows console app and they communicate with each other. The socket is opened and data is sent and received in windows app, but my android app does not receive the answer which sent by windows. I watch the packets in my android and I saw the packets are coming but I do not know why my app do not receive it!
windows app server class:
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
public Server()
{
Console.WriteLine("\nStarting server...");
this.tcpListener = new TcpListener(IPAddress.Any, 1234);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
Console.WriteLine("\nWaiting for clients to connect...");
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
Console.WriteLine("\nIncoming from client...");
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
try
{
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
Console.WriteLine("\nReceived: \n\n" + encoder.GetString(message, 0, bytesRead));
//By FMR
string response = "random responsive: " + new Random().Next(1000).ToString() + "\n";//"\r\n";
//writeData(clientStream, response);
byte[] msg = System.Text.Encoding.ASCII.GetBytes(response);
// Send back a response.
clientStream.Write(msg, 0, msg.Length);
clientStream.Flush();
Console.WriteLine("\nResponed ..." + response);
}
}
catch (Exception ex)
{
Console.WriteLine("\nException while: " + ex.Message);
}
tcpClient.Close();
}
}
my android thread:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Socket socket = null;
ServerSocket serverSocket = null;
Boolean bRun = true;
try {
socket = new Socket(ip, port);
if(outputStream == null) {
outputStream = new DataOutputStream(socket.getOutputStream());
}
// become server
serverSocket = new ServerSocket(port);
Log.i(G.TAG, "before serverSocket.accept");
socket = serverSocket.accept();
Log.i(G.TAG, "response recieve: ");
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (Exception e) {
try {
serverSocket.close();
} catch (IOException e1) {
Log.e(G.TAG, "serverSocket.close() e: " + e1.getMessage());
}
try {
socket.close();
} catch (IOException e1) {
Log.e(G.TAG, "socket.close() e: " + e1.getMessage());
}
}
Log.i(G.TAG, "after start recieve: ");
while (bRun) {
try {
Log.i(G.TAG, "while start: ");
String message = inputStream.readLine();
Log.i(G.TAG, "response message: " + message);
if (message != null) {
setListMessage(false, message);
}
}
catch (IOException e) {
bRun = false;
Log.e(G.TAG, "while bRun e: " + e.getMessage());
}
}
}
});
thread.start();
// in another function, my message is sent successfully from android and receive in windows
I found the problem, this line
socket = serverSocket.accept();
made the problem when I comment the line, the android app received the response!
Does anybody know why?
I have created a server and client with Android and Arduino but I have a problem. Android reads only one time. Why? this is my code:
Client Android:
new Thread(new ClientThread()).start();
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName("192.168.1.240");
socket = new Socket(serverAddr, 8888);
if(socket == null)System.out.println("SOCKET NULL");
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),true);
inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
msgFromServer = inFromServer.readLine();
System.out.println(msgFromServer);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (socket != null) {
System.out.println("STOP SOCKET");
// close socket
}
}
}
}
Arduino Server:
void loop() {
YunClient client = server.accept();
sensorValue = analogRead(sensorPin);
String myString = String(sensorValue);
if (client) {
String command = "none";
command = client.readString();
Serial.println(sensorValue);
client.print(myString+"\n");
}
}
LOGCAT:
07-24 11:44:24.468: D/OpenGLRenderer(19693): Enabling debug mode 0
07-24 11:44:25.363: I/System.out(19693): 121
121 is the value from Arduino. But this is showing only once.
It works only once. I want receive data from the Arduino every second.
Thank you guys!
You need to take the accept out of the loop. otherwise it send a string and wait for another connect from client.
YunClient client = server.accept();
void loop() {
sensorValue = analogRead(sensorPin);
String myString = String(sensorValue);
if (client) {
String command = "none";
command = client.readString();
Serial.println(sensorValue);
client.print(myString+"\n");
}
}
Also, I don't see where the client sends something to the server. Instead of System.out.println should't it be out.println?
I am trying to sending and receiving data between two mobile phones. Right now I can send data from one device (device 1) to another (device 2), however, when I am reading data in the same device (device 1) I am getting following error:
java.net.SocketException: Socket is closed
I am using the following code to read data:
SocketServerReadThread socketServerReadThread = new SocketServerReadThread(socket);
socketServerReadThread.run();
private class SocketServerReadThread extends Thread {
private Socket mySocket;
SocketServerReadThread(Socket socket) {
mySocket = socket;
}
#Override
public void run() {
try {
inputStream = mySocket.getInputStream();
byte[] buffer = new byte[1024];
byteArrayOutputStream = new ByteArrayOutputStream(1024);
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1){
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
msgRead.setText(" Response: "+response);
}
});
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
message += "Read Something wrong! " + e1.toString() + "\n";
}
}
}
I would appreciate if anyone could help me to solve the problem.
private class SocketServerReadThread extends Thread {
private Socket mySocket;
SocketServerReadThread(Socket socket) {
this.mySocket = socket;
}
BufferedReader input;
input = new BufferedReader(new InputStreamReader(
this.mySocket.getInputStream()));
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
System.out.printf("Message read is -> %s%n", read);
if (read != null) {
msgRead.setText(" Response: "+response);
}
}catch(Exception e){}}}}
I have the following web server class found here. I need to write an Android application(client) which can retrieve a file from this server. It would be great if anyone would be able to help me to do it. Thank you.
Server host address is: My-PC/ipaddress
When I execute the client it gives an exception.
java.net.ConnectException: Connection refused: connect
WebServer.Java
import java.io.*;
import java.net.*;
public class WebServer extends Thread {
public WebServer() {
this.start();
}
private void displayString(String string) { //an alias to avoid typing so much!
System.out.println(string);
}
private static final int UMBRA_PORT = 30480;
private static final int ROOM_THROTTLE = 200;
private InetAddress hostAddress;
//this is a overridden method from the Thread class we extended from
public void run() {
//we are now inside our own thread separated from the gui.
ServerSocket serversocket = null;
//To easily pick up lots of girls, change this to your name!!!
displayString("The simple httpserver v. 0000000000\nCoded by Jon Berg" +
"<jon.berg[on server]turtlemeat.com>\n\n");
//Pay attention, this is where things starts to cook!
try {
//print/send message to the guiwindow
displayString("Trying to bind to localhost on port " + Integer.toString(UMBRA_PORT) + "...");
//make a ServerSocket and bind it to given port,
//serversocket = new ServerSocket(port);
}
catch (Exception e) { //catch any errors and print errors to gui
displayString("\nFatal Error:" + e.getMessage());
return;
}
// Attempt to get the host address
try
{
hostAddress = InetAddress.getLocalHost();
}
catch(UnknownHostException e)
{
System.out.println("Could not get the host address.");
return;
}
// Announce the host address
System.out.println("Server host address is: "+hostAddress);
// Attempt to create server socket
try
{
serversocket = new ServerSocket(UMBRA_PORT,0,hostAddress);
}
catch(IOException e)
{
System.out.println("Could not open server socket.");
return;
}
// Announce the socket creation
System.out.println("Socket "+serversocket+" created.");
displayString("OK!\n");
//go in a infinite loop, wait for connections, process request, send response
while (true) {
displayString("\nReady, Waiting for requests...\n");
try {
//this call waits/blocks until someone connects to the port we
//are listening to
Socket connectionsocket = serversocket.accept();
//figure out what ipaddress the client commes from, just for show!
InetAddress client = connectionsocket.getInetAddress();
//and print it to gui
displayString(client.getHostName() + " connected to server.\n");
//Read the http request from the client from the socket interface
//into a buffer.
BufferedReader input =
new BufferedReader(new InputStreamReader(connectionsocket.
getInputStream()));
//Prepare a outputstream from us to the client,
//this will be used sending back our response
//(header + requested file) to the client.
DataOutputStream output =
new DataOutputStream(connectionsocket.getOutputStream());
//as the name suggest this method handles the http request, see further down.
//abstraction rules
http_handler(input, output);
}
catch (Exception e) { //catch any errors, and print them
displayString("\nError:" + e.getMessage());
}
} //go back in loop, wait for next request
}
//our implementation of the hypertext transfer protocol
//its very basic and stripped down
private void http_handler(BufferedReader input, DataOutputStream output) {
int method = 0; //1 get, 2 head, 0 not supported
String http = new String(); //a bunch of strings to hold
String path = new String(); //the various things, what http v, what path,
String file = new String(); //what file
String user_agent = new String(); //what user_agent
try {
//This is the two types of request we can handle
//GET /index.html HTTP/1.0
//HEAD /index.html HTTP/1.0
String tmp = input.readLine(); //read from the stream
String tmp2 = new String(tmp);
tmp.toUpperCase(); //convert it to uppercase
if (tmp.startsWith("GET")) { //compare it is it GET
method = 1;
} //if we set it to method 1
if (tmp.startsWith("HEAD")) { //same here is it HEAD
method = 2;
} //set method to 2
if (method == 0) { // not supported
try {
output.writeBytes(construct_http_header(501, 0));
output.close();
return;
}
catch (Exception e3) { //if some error happened catch it
displayString("error:" + e3.getMessage());
} //and display error
}
//}
//tmp contains "GET /index.html HTTP/1.0 ......."
//find first space
//find next space
//copy whats between minus slash, then you get "index.html"
//it's a bit of dirty code, but bear with me...
int start = 0;
int end = 0;
for (int a = 0; a < tmp2.length(); a++) {
if (tmp2.charAt(a) == ' ' && start != 0) {
end = a;
break;
}
if (tmp2.charAt(a) == ' ' && start == 0) {
start = a;
}
}
path = tmp2.substring(start + 2, end); //fill in the path
}
catch (Exception e) {
displayString("errorr" + e.getMessage());
} //catch any exception
//path do now have the filename to what to the file it wants to open
displayString("\nClient requested:" + new File(path).getAbsolutePath() + "\n");
FileInputStream requestedfile = null;
try {
//try to open the file,
requestedfile = new FileInputStream(path);
}
catch (Exception e) {
try {
//if you could not open the file send a 404
output.writeBytes(construct_http_header(404, 0));
//close the stream
output.close();
}
catch (Exception e2) {}
displayString("error" + e.getMessage());
} //print error to gui
//happy day scenario
try {
int type_is = 0;
//find out what the filename ends with,
//so you can construct a the right content type
if (path.endsWith(".zip") ) {
type_is = 3;
}
if (path.endsWith(".jpg") || path.endsWith(".jpeg")) {
type_is = 1;
}
if (path.endsWith(".gif")) {
type_is = 2;
}
if (path.endsWith(".ico")) {
type_is = 4;
}
if (path.endsWith(".xml")) {
type_is = 5;
}
//write out the header, 200 ->everything is ok we are all happy.
output.writeBytes(construct_http_header(200, 5));
//if it was a HEAD request, we don't print any BODY
if (method == 1) { //1 is GET 2 is head and skips the body
byte [] buffer = new byte[1024];
while (true) {
//read the file from filestream, and print out through the
//client-outputstream on a byte per byte base.
int b = requestedfile.read(buffer, 0,1024);
if (b == -1) {
break; //end of file
}
output.write(buffer,0,b);
}
//clean up the files, close open handles
}
output.close();
requestedfile.close();
}
catch (Exception e) {}
}
//this method makes the HTTP header for the response
//the headers job is to tell the browser the result of the request
//among if it was successful or not.
private String construct_http_header(int return_code, int file_type) {
String s = "HTTP/1.0 ";
//you probably have seen these if you have been surfing the web a while
switch (return_code) {
case 200:
s = s + "200 OK";
break;
case 400:
s = s + "400 Bad Request";
break;
case 403:
s = s + "403 Forbidden";
break;
case 404:
s = s + "404 Not Found";
break;
case 500:
s = s + "500 Internal Server Error";
break;
case 501:
s = s + "501 Not Implemented";
break;
}
s = s + "\r\n"; //other header fields,
s = s + "Connection: close\r\n"; //we can't handle persistent connections
s = s + "Server: SimpleHTTPtutorial v0\r\n"; //server name
switch (file_type) {
//plenty of types for you to fill in
case 0:
break;
case 1:
s = s + "Content-Type: image/jpeg\r\n";
break;
case 2:
s = s + "Content-Type: image/gif\r\n";
break;
case 3:
s = s + "Content-Type: application/x-zip-compressed\r\n";
break;
case 4:
s = s + "Content-Type: image/x-icon\r\n";
case 5:
s = s + "Content-Type: text/xml\r\n";
break;
default:
s = s + "Content-Type: text/html\r\n";
break;
}
////so on and so on......
s = s + "\r\n"; //this marks the end of the httpheader
//and the start of the body
//ok return our newly created header!
return s;
}
}
Client.Java
public class WatchMeManagerClient {
private static Socket socket;
private static PrintWriter printWriter;
public static void main(String[] args) throws Exception {
try {
URL url;
URLConnection urlConn;
DataInputStream dis;
url = new URL("http://ipaddress/xml/userGroup.xml");
urlConn = url.openConnection();
urlConn.setDoInput(true);
urlConn.setUseCaches(false);
dis = new DataInputStream(urlConn.getInputStream());
String s;
while ((s = dis.readLine()) != null) {
System.out.println(s);
}
dis.close();
}
catch (MalformedURLException mue) {
System.out.println(mue.toString());
} catch (IOException ioe) {
System.out.println(ioe.toString());
}
}
}
When I run the code on PC it works. But when I try to execute it on the Android Device it gives following errors.
Such problems are either due to one of the following:
The port is wrong
Firewall is stopping it.
Using Sockets require the following permission which I think you are missing:
<uses-permission android:name="android.permission.INTERNET" />
Did you allow internet access in your manifest?
<uses-permission android:name="android.permission.INTERNET"/>
I have a client in Android and server in C#, they communicate through socket.
I have this problem - if I run my client app in debug mode and place a breakpoint in right place - it works perfectly, but without it it doesn't.
Client sends adress of an image to server, server makes a thumbnail of it, converts it to byte[] and sends it back. Client gets the byte[], converts it back into image and shows it.
I've also found out that when it doesn't get the right byte[] its size is 2896 and sometimes 1448, no matter what the original size of the array sent was.
Here's the client:
private void connectSocket(String a){
try {
InetAddress serverAddr = InetAddress.getByName("192.168.1.2");
Socket socket = new Socket(serverAddr, 4444);
String message = a;
flag = 0;
if(a.indexOf(".jpg")>0){
flag = 1;
}
ListItems.clear();
if(!a.equalsIgnoreCase("get_drives"))){
//.....
}
if(!ListItems.isEmpty()){
if(ListItems.get(0).matches("^[A-Z]{1}:$")){
ListItems.set(0, ListItems.get(0)+"\\");
}
}
PrintWriter out = null;
BufferedReader in = null;
InputStream is = null;
try {
out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
is = socket.getInputStream();
out.println(message);
String text = "";
String finalText = "";
if(flag!=1){
while ((text = in.readLine()) != null) {
finalText += URLDecoder.decode(text, "UTF-8");
}
String[] result = finalText.split("#");
for(int i = 0; i<result.length; i++)
ListItems.add(result[i]);
}
if(flag ==1){
byte[] buffer = new byte[9999];
//placing breakpoint at the next line or before it makes it work fine
int size = is.read(buffer);
//but placing a breakpoint at the line below doesn't make it work
//it starts getting another byte array
byte[] bufffer2 = new byte[size];
for(int g = 0; g<size;g++){
bufffer2[g] = buffer[g];
}
//is.read(bufffer2);
//int read = is.read(buffer);
image = (ImageView)findViewById(R.id.imageView1);
//while ((text = in.readLine()) != null) {
// byte[] b = in.readLine().getBytes();
Bitmap bmp=BitmapFactory.decodeByteArray(bufffer2,0,bufffer2.length);
image.setImageBitmap(bmp);
//}
}
adapter.notifyDataSetChanged();
} catch(Exception e) {
Log.e("TCP", "S: Error", e);
} finally {
socket.close();
}
} catch (UnknownHostException e) {
Log.e("TCP", "C: UnknownHostException", e);
e.printStackTrace();
} catch (IOException e) {
Log.e("TCP", "C: IOException", e);
e.printStackTrace();
}
}
Here's the server:
public class serv {
public static void Main() {
try {
IPAddress ipAd = IPAddress.Parse("192.168.1.2");
TcpListener myList=new TcpListener(ipAd,4444);
m:
myList.Start();
Socket s=myList.AcceptSocket();
byte[] b=new byte[100];
int k=s.Receive(b);
char cc = ' ';
string test = null;
Console.WriteLine("Recieved...");
for (int i = 0; i < k-1; i++)
{
Console.Write(Convert.ToChar(b[i]));
cc = Convert.ToChar(b[i]);
test += cc.ToString();
}
string[] response = null;
ASCIIEncoding asen = new ASCIIEncoding();
switch (test)
{
default:
MyExplorer(test, s);
break;
}
s.Close();
myList.Stop();
goto m;
}
catch (Exception e) {
Console.WriteLine("Error..... " + e.StackTrace);
}
}
public static void MyExplorer(string r, Socket s){
Image imgThumb = null;
if (r.Contains(".jpg"))
{
Image image = null;
image = Image.FromFile(r);
// Check if image exists
if (image != null)
{
imgThumb = image.GetThumbnailImage(100, 100, null, new IntPtr());
s.Send(imageToByteArray(imgThumb));
byte[] b = imageToByteArray(imgThumb);
}
return;
}
}
public static byte[] imageToByteArray(System.Drawing.Image imageIn)
{
MemoryStream ms = new MemoryStream();
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
return ms.ToArray();
}
}
The read(byte []) method in InputStream reads as many bytes as currently available. It does not necessarily mean that there won't be more bytes available later. So you need to do something like
while(true) {
int s = is.read(buffer);
if(s == -1) break;
// else
add read buffer to image array
}
extract image from image array
where "image array" is some byte array where you keep adding the read buffer until you reach then end of the stream.
The reason your code works with the breakpoint is that by the time you go through the debugger the whole stream is available, while in non-debug the whole stream is not yet available when you do the read.
The difference is likely due to the fact that on the debugger, you are able to slow and stop the application - this gives time for the server to respond to your call. It looks like you are not using any asynchronous methods to call connect socket (well, I can't see any evidence of this from your code anyway).
To fix this, you should try extending the AsyncTask object examples here
EDIT: #Carsten probably has the correct solution, but you should STILL use an AsyncTask if you are not already.