I'm new in the scala world, so excuse my trivial question. :) I just want to open a socket to a port and sand and receive messages.
If I receive a HELO, I want to react with a message, but I'm not able to write to the socket in any way.
I used nc to listen for incoming connections:
nc -k -l 127.0.0.1 3333
When the client is connected I write
HELO
in the netcat, but the client sends no answer.
Here is my scala code:
package hello
import java.io._
import java.net.{ InetAddress, ServerSocket, Socket, SocketException }
import java.util.Random
import scala.actors.Actor
import scala.actors.Actor._
object HelloWorld extends {
def main(args: Array[String]) {}
val ia = InetAddress.getByName("localhost");
val socket = new Socket(ia, 3333)
val out = new ObjectOutputStream(
new DataOutputStream(this.socket.getOutputStream))
val in = new DataInputStream(socket.getInputStream())
println("Starting client");
var i = 0;
/* The actor!
*
*/
val myActor = actor {
loop {
receive {
case s: String => {
if (s.startsWith("HELO")) {
println("DEBUG: RECEIVED HELO=>SENDING AUTH!")
this.out.writeUTF("HALLO")
this.out.flush();
} else {
println("received:" + s);
}
}
case _ => println("I have no idea what I just got.")
}
}
}
/*
* Testing the actor!
*
*/
myActor ! "foobar";
while (!socket.isConnected()) {
println("Not connected waiting")
Thread.sleep(5000);
}
if (socket.isConnected()) {
println("connected");
}
try {
while (true) {
i += 1;
val x = in.readLine()
myActor ! x;
Thread.sleep(500);
}
} catch {
case e: IOException =>
e.printStackTrace()
}
}
The receiving works just fine, and the actor reacts on the incoming message, but the write is never done. Am I just oversee something, or is my code wrong for sending to an outputSteam.
Heres my output from the console window:
Starting client
connected
received:foobar
DEBUG: RECEIVED HELO=>SENDING AUTH!
If this code is truly the code you are using, it has a serious problem: it is using threads from inside a static initializer.
Here:
object HelloWorld extends {
Extends what?
def main(args: Array[String]) {}
No main method, so everything else is inside the constructor to object HelloWorld. Basically, that means everything using threads (including actors) is unreliable. Put this stuff inside the main method.
I'm not familiar with netcat, but is it possible that it's just not printing the "HALLO" response because it's encoded in a way that netcat can't make sense of (i.e. Java's serialization format)? Does it work if you don't wrap the output stream in an ObjectOutputStream?
Related
I am making a Minecraft mod in which I want to have a socket server running in the background waiting for a message from the python client.
The server is running in a thread.
Here is the code in which I start the thread:
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
InterPythonJavaCommunicatorServer.begin(socket, sockIn, sockOut);
}catch (IOException e){
System.out.println("Woah! Somethings gone wrong! ringing a alarm now!");
}
}
});
t.start();
t.join();
And the entire Server class
package com.satyamedh.minecraft_ai_helper.communicator;
import com.satyamedh.minecraft_ai_helper.Movement;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.net.Socket;
public class InterPythonJavaCommunicatorServer{
public static void begin(Socket socket, BufferedReader sockIn, BufferedWriter sockOut) throws IOException {
boolean done = false;
while (true) {
System.out.println("Test!");
boolean ready = sockIn.ready();
if(!ready) {
return;
}
try {
String response = sockIn.readLine(); // Stops Here!
System.out.println(response);
//if (response == null) {
//System.out.println("Remote process closed the connection.");
//done=true;
//}
if (response.equals("forward\n")){
boolean o = Movement.forward(1);
if (o){
sockOut.write("done");
sockOut.flush();
}
}
} catch (IOException e) {
System.out.println("Welp! ALARM BOI!");
}
}
}
}
I have breakpoined the entire code and it seems to stop on String response = sockIn.readLine();. And the Test! message only runs once.
Ps: I have googled for hours searching why! cant seem to find anything related!
I know it might be very stupid and easiely caught out :)
Edit: As #DevParzival Said I tried using t.join(); but it still does the same! I have edited the above code to match my current one.
Edit2: here is the client code(python)
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 1243))
server_socket.listen(5)
print(
"TCPServer Waiting for client on port 1243")
while 1:
client_socket, address = server_socket.accept()
print(
"I got a connection from ", address)
while 1:
data = input("SEND( TYPE q or Q to Quit):")
if data == 'Q' or data == 'q':
client_socket.send(bytes(data, encoding='utf8'))
client_socket.close()
break
else:
client_socket.send(bytes(data, encoding='utf8'))
data = client_socket.recv(512)
if data == 'q' or data == 'Q':
client_socket.close()
break
else:
print("RECEIVED:", data)
Thx in advance
Try to send NewLine | CHR(10) | \n character at the end of python packet payload, if you use socketIn.readLine() in a receiving side it waits for a line delimiter before return.
If you want to study Java NonBlocking NIO socket you may study my example program here, please note NIO socket need quite a different approach
https://stackoverflow.com/a/26312841/185565
I made a python server and a java client. My problem is simple:
The server receives the message from client, but the client doesn't get the reply.
Java Client:
package fgd;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
public class fdassd {
public static void main(String[] args){
new Thread(){
public void run(){
while (true)
{
try {Socket socke=new Socket("censored",1977);
DataOutputStream dout=new DataOutputStream(socke.getOutputStream());
DataInputStream din = new DataInputStream(socke.getInputStream());
dout.writeUTF("Heey");
dout.flush();
String str = din.readUTF();
System.out.println(str);
dout.close();
socke.close();
}catch(Exception e){
e.printStackTrace();
}
try {
Thread.sleep(17000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}
}
Python Server:
hosto = '0.0.0.0'
porto = 1979
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created!'
try:
soc.bind((hosto, porto))
except socket.error as e:
print(e)
sys.exit()
print 'Socket bind complete'
soc.settimeout(30)
soc.listen(10)
print 'Listening...'
timeout = 8
timeout_start = time.time()
while time.time() < timeout_start + timeout:
try:
conn, addr = soc.accept()
if addr[0] != opip:
conn.shutdown(socket.SHUT_RDWR)
conn.close()
else:
msg = conn.recv(1024)
print ('--------------------------------------')
print (msg)
conn.send((playername).encode('UTF-8'))
print ('Success! The following command has been sent to: ' + opip + ':' + playername )
print ('--------------------------------------')
soc.close()
break
except socket.timeout as e:
print(e,': Server not online or wrong ip')
soc.close()
break
else:
I've seen a very similar question where the answer was to add to lines before conn.send (Link: Socket Java client - Python Server).
But I can't use the solution in that question, because
conn.send(len(message_to_send).to_bytes(2, byteorder='big'))
doesn't seem to work in python 2.x .That means I need another solution to send the message with UTF-8 but I can't figure out what to do.
Regards
Add the following line, before you send the playername. This should work in both python2 and 3:
conn.send(struct.pack(">H", len(playername)))
This line will prefix the length of the player name to the message, as is required by the java DataInputStream#readUTF method. It's encoded as a two-byte integer, hence the 'H' in the struct.pack call.
You will also need an import struct statement.
See Python 2,3 Convert Integer to "bytes" Cleanly for more information.
I recently tried creating a socket server which can connect to multiple clients... I was too lazy to write a separate program for the client so I'm just using telnet.
The first time I connect(using telnet), it works fine... but the second telnet connection just hangs and the cmd screen goes blank...
Even the first connection gets hanged after sending a string.
Any help is appreciated
Here's the code:
Chatserver.java
I would really appreciate I if someone would correct the mistakes in the code and post it
You could have a look at it if you want but it might be easier if you just clicked the hyperlink and viewed the image:
package chatserver;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
class Chat extends Thread {
#Override
public void run() {
Chat server = new Chat();
try {
server.SERVER();
} catch (Exception ex) {
Logger.getLogger(Chat.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void SERVER() throws Exception {
ServerSocket SRVSOCK = new ServerSocket(8068);
Socket SOCK = SRVSOCK.accept();
InputStreamReader IR = new InputStreamReader(SOCK.getInputStream());
BufferedReader BR = new BufferedReader(IR);
PrintStream PS = new PrintStream(SOCK.getOutputStream());
PS.println("What is your name: ");
String name = BR.readLine();
String Message = BR.readLine();
PS.println(name + " : " + Message);
}
}
public class ChatServer {
public static void main(String[] args) {
Chat c1 = new Chat();
Chat c2 = new Chat();
while (true) {
c1.start();
c2.start();
}
}
}
Guys,
Today I typed up the same code in python as I am much more familiar with it than I am with Java
I have succeeded in connecting to multiple clients but am unable to see outputs from chat() yet...
I would like to know what mistake I made in this code below and would be very grateful if someone helps me transcribe it to Java:
#!/usr/bin/env python3
import socket
import threading
import time
clients = []
addr = []
HOST = '127.0.0.1'
PORT = 8068
client_no = 0
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
print('Socket bind complete')
def connect(clnt_no):
while True:
s.listen(1)
print('searching for clients')
clnt, adr = s.accept()
clients.append(clnt)
addr.append(adr)
print('connected to: ',addr[clnt_no])
# print(len(clients))
clnt_no += 1
client_no = clnt_no
def chat():
while True:
for x in range(0, client_no):
data = clients[x] = recv(1204)
if data:
for y in range(0, client_no):
clients[y].send('from client ', x, ' ', data)
else:
print('no data recieved from any client')
def Main():
conn = threading.Thread(target=connect, args=[0])
cht = threading.Thread(target=chat)
# while True:
conn.start()
cht.start()
if(__name__ == '__main__'):
Main()
Thanks in advance
Two problems:
First, every instance of Chat is listening on port 8068. You can only have one ServerSocket listening on a particular port, though it is free to accept() multiple connections. If you paid attention to the exceptions you’re getting instead of ignoring them, you would see an exception informing you of this.
Second, since the start() method of Thread returns immediately rather than waiting for the thread to finish, your while loop is creating hundreds, if not thousands, of threads. The only reason your system isn’t overwhelmed by them is because, as I mentioned above, all but the very first instance are immediately failing to bind their ServerSockets, so they return fairly quickly.
In summary, you need to create one server, with one ServerSocket. You will need to call accept() inside a loop, but you must not create more than one ServerSocket.
I have just started learning java. I modified the client side code for a server/client communication program, by creating two threads for the client side, main thread for receiving user's input, and inputThread for receiving server's response. I am sure that server has sent the response to client, however, no response message is obtain at client.
Here is my code. Can anyone help me to figure it out? Thanks
package clientnio;
import java.net.*;
import java.nio.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Scanner;
public class ClientNIO {
public static int bufferLen = 50;
public static SocketChannel client;
public static ByteBuffer writeBuffer;
public static ByteBuffer readBuffer;
public static void main(String[] args) {
writeBuffer = ByteBuffer.allocate(bufferLen);
readBuffer = ByteBuffer.allocate(bufferLen);
try {
SocketAddress address = new InetSocketAddress("localhost",5505);
System.out.println("Local address: "+ address);
client=SocketChannel.open(address);
client.configureBlocking(false);
//readBuffer.flip();
new inputThread(readBuffer);
/*
String a="asdasdasdasddffasfas";
writeBuffer.put(a.getBytes());
writeBuffer.clear();
int d=client.write(writeBuffer);
writeBuffer.flip();
*/
while (true) {
InputStream inStream = System.in;
Scanner scan = new Scanner(inStream);
if (scan.hasNext()==true) {
String inputLine = scan.nextLine();
writeBuffer.put(inputLine.getBytes());
//writeBuffer.clear();
System.out.println(writeBuffer.remaining());
client.write(writeBuffer);
System.out.println("Sending data: "+new String(writeBuffer.array()));
writeBuffer.flip();
Thread.sleep(300);
}
}
}
catch(Exception e) {
System.out.println(e);
}
}
}
class inputThread extends Thread {
private ByteBuffer readBuffer;
public inputThread(ByteBuffer readBuffer1) {
System.out.println("Receiving thread starts.");
this.readBuffer = readBuffer1;
start();
}
#Override
public void run() {
try {
while (true) {
readBuffer.flip();
int i=ClientNIO.client.read(readBuffer);
if(i>0) {
byte[] b=readBuffer.array();
System.out.println("Receiving data: "+new String(b));
//client.close();
//System.out.println("Connection closed.");
//break;
}
Thread.sleep(100);
}
}
catch (Exception e) {
System.out.println(e);
}
}
}
Disclaimer: I'm not an active user of Java. (I only used it in school.)
Advice: I think it will greatly simplify the debugging process if you use blocking mode, at least until your code example is working correctly. (Currently your code does not seem to benefit from the non-blocking mode.)
I have identified two issues, culminating into four possible lines of code that may require changing:
When a ByteBuffer allocates its backing array, it sets itself ready to write by setting position to zero and limit to the capacity of that array. Your two uses of ByteBuffer.flip() (in the writing loop and the reading loop respectively) seem to be contrary to the convention.
Calling the ByteBuffer.array() method always returns the whole backing array, thus it always has size bufferLen. Because of this, a String constructed from the full-size array may contain junk from a previous transmission.
Typically, the array needs to be trimmed to the transmission size, and the conversion between a String and a byte array must use the same encoding as the server.
My suggested changes for first issue: (Note: I don't know how to fix the array trimming and encoding issue.)
writeBuffer.put(inputLine.getBytes());
writeBuffer.flip(); // <--here
client.write(writeBuffer);
...
writeBuffer.clear(); // <-- should be clear() instead of flip()
Thread.sleep(300);
// readBuffer.flip(); // <-- remove this line
int i=ClientNIO.client.read(readBuffer);
if(i>0) {
readBuffer.flip(); // <-- move it here
byte[] b=readBuffer.array();
System.out.println("Receiving data: "+new String(b));
...
}
References
http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/ByteBuffer.html
http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/channels/SocketChannel.html
Socketchannel always null
http://www.exampledepot.com/egs/java.nio.charset/ConvertChar.html
Calling flip() on a buffer prior to reading it is wrong. Don't do that. You need to flip it prior to writing from it, or getting from it, and compact() afterwards.
I attempted to create a PHP script which determines if the server (the computer which hosts the java program listed below) is running or not, If it is, the php funciton should return true, if not it returns false.
Here is the server:
package darestium.minecraft.server;
import java.io.BufferedReader;
import java.net.*;
import java.io.*;
public class Server {
private static ServerSocket socket;
private static Socket connection;
private static String command = new String();
private static String responseStr = new String();;
private static int port = 4343;
public static void main(String args[]) {
System.out.println("Signal Server is running.");
try {
socket = new ServerSocket(port);
while (true) {
connection = socket.accept();
InputStreamReader inputStream = new InputStreamReader(connection.getInputStream());
DataOutputStream response = new DataOutputStream(connection.getOutputStream());
BufferedReader input = new BufferedReader(inputStream);
command = input.readLine();
response.writeBytes(responseStr);
response.flush();
//response.close();
System.out.println("Running");
}
} catch (IOException e) {
System.out.println("Fail!: " + e.toString());
}
System.out.println("Closing...");
}
}
And here is the client:
<?
function isRunning() {
$address = 'darestium.dyndns-free.com';
$port = 4343;
$socket = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp'));
$message = 'loolololol';
try {
socket_connect($socket, $address, $port);
$status = socket_sendto($socket, $message, strlen($message), MSG_EOF, $address, $port);
if ($status != false) {
return true;
}
return false;
} catch (Exception $e) {
return false;
}
}
?>
The following are the error messages that show up on the php page that echos out the result of the function like so:
include('server.php');
echo isRunning();
Then the error messages:
Warning: socket_connect() [function.socket-connect]: unable to connect [0]: No connection could be made because the target machine actively refused it. in C:\Users\darestium\Documents\Portables\xampp\htdocs\darestium\minecraftserver.php on line 9
Notice: Use of undefined constant MSG_EOF - assumed 'MSG_EOF' in C:\Users\darestium\Documents\Portables\xampp\htdocs\darestium\minecraftserver.php on line 11
Warning: socket_sendto() expects parameter 4 to be long, string given in C:\Users\darestium\Documents\Portables\xampp\htdocs\darestium\minecraftserver.php on line 11
I was wondering how I could fix this issue. Also, I would like to be able to send messages to the server, any ideas how I could do this? I am basing this off Simple Java TCP Server and PHP Client Problems
Note: that I am very new to Sockets, and Server/Client communication.
Edit:
#VideanuAdrian OK, just port forwarded the port 4343 and it no longer shows up with the first error, but the function always seems to return false, and the last two errors still show.
You should not close the DataOutputStream object in your server.
Just comment the line response.close(); in your server and the program should work.
When running a Client/Server you need to know if the user that runs the app has access to the port. Ports to 1024 are reserved by the system know apps/services. That´s point 1.
Point 2: One of the best ways is to run the server inside a connection-thread approach. Running in this way, when a new client request arrives, the server can delegate the request handle to the connection thread.
Point 3: The message is related to the protocol. If you are using a built protocol like HTTP or FTP, you must use the protocol rules. If not, you could built your own rules for the message request/response.
I recomend you to read the Java Networking Tutorial before continue. Run all Java examples. Later, you could mix with PHP. The more information about sockets and protocols you have, the better your programm will be.
http://docs.oracle.com/javase/tutorial/networking/
Hope this can help you.