java.net.SocketException: Broken pipe (Please give me design advice.) - java

public class NewsServer {
Socket socket;
ArticleData ad;
DataType dt;
boolean isRecv = false;
DataOutputStream dos;
private static final int THREAD_CNT = 5;
private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_CNT, new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
}
});
private static ExecutorService pollThreadPool = Executors.newSingleThreadExecutor();
public NewsServer() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(7777);
while (true) {
socket = serverSocket.accept();
try {
threadPool.execute(new WriteThread(socket));
pollThreadPool.execute(new PollingThread(socket));
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (IOException e) {
try {
serverSocket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
// polling
class PollingThread implements Runnable {
private Socket tsocket;
public PollingThread(Socket socket) {
this.tsocket = socket;
}
#Override
public void run() {
try {
DataOutputStream dos = new DataOutputStream(tsocket.getOutputStream());
ArticleData ads = new ArticleData(dos);
while (!tsocket.isClosed()) {
ads.sendPolling();
Thread.sleep(Constant.POLLING_INTERVAL);
}
} catch (SocketException e) {
try {
tsocket.close();
} catch (IOException ie) {
ie.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
tsocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// send news
class WriteThread implements Runnable {
private Socket tsocket = null;
private boolean readySend = true;
private boolean doSend = true;
public WriteThread(Socket socket) {
this.tsocket = socket;
}
#Override
public void run() {
int dataTypeDiv = 0;
try {
DataOutputStream dos = new DataOutputStream(tsocket.getOutputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(tsocket.getInputStream()));
NewsDataFile newsDataFile = null;
StringBuffer bodyBuffer = new StringBuffer();
while (true) {
if (doSend) {
newsDataFile = sendNewsData(dos);
doSend = false;
}
try {
int readByteCount = br.read();
if (readByteCount == DataType.STX) {
doSend = false;
} else if (readByteCount == DataType.ETX) {
if (dataTypeDiv == DataType.ACK) {
doSend = true;
if (newsDataFile != null) {
newsDataFile.removeNewsData();
}
} else if (dataTypeDiv == DataType.NAK) {
doSend = true;
}
} else if (readByteCount == DataType.ACK) {
dataTypeDiv = readByteCount;
} else if (readByteCount == DataType.NAK) {
dataTypeDiv = readByteCount;
} else {
bodyBuffer.append(readByteCount);
doSend = false;
}
} catch (IOException e) {
readySend = true;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
tsocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* #param dos
* #throws Exception
* #throws ParseException
* #throws IOException
*/
private NewsDataFile sendNewsData(DataOutputStream dos) throws Exception, ParseException, IOException {
String jsonNewsData = null;
NewsDataFile newsDataFile = new NewsDataFile();
while (true) {
jsonNewsData = newsDataFile.getJsonNewsData();
if (jsonNewsData != null) {
JSONParser jsonParse = new JSONParser();
JSONObject articleObject = (JSONObject) jsonParse.parse(jsonNewsData);
String status = (String) articleObject.get("status");
String sn = (String) articleObject.get("sn");
String code = (String) articleObject.get("code");
String wdate = (String) articleObject.get("wdate");
String sdate = (String) articleObject.get("sdate");
String cate = (String) articleObject.get("cate");
String title = (String) articleObject.get("title");
String reporter = (String) articleObject.get("reporter");
String stockcd1 = (String) articleObject.get("stockcd1");
String stockcd2 = (String) articleObject.get("stockcd2");
String stockcd3 = (String) articleObject.get("stockcd3");
String stockcd4 = (String) articleObject.get("stockcd4");
String stockcd5 = (String) articleObject.get("stockcd5");
String stockcd6 = (String) articleObject.get("stockcd6");
String stockcd7 = (String) articleObject.get("stockcd7");
String stockcd8 = (String) articleObject.get("stockcd8");
String prepare1 = (String) articleObject.get("prepare1");
String prepare2 = (String) articleObject.get("prepare2");
String body = (String) articleObject.get("body");
ArticleData articleData = new ArticleData(dos);
articleData.setArticle(status, sn, code, wdate, sdate, cate, title, reporter, stockcd1, stockcd2,
stockcd3, stockcd4, stockcd5, stockcd6, stockcd7, stockcd8, prepare1, prepare2, body);
articleData.writeDataExternal();
dos.flush();
articleData = null;
articleObject = null;
jsonParse = null;
break;
}
}
return newsDataFile;
}
}
public static final byte[] getbytes(byte src[], int offset, int length) {
byte dest[] = new byte[length];
System.arraycopy(src, offset, dest, 0, length);
return dest;
}
public static void main(String[] args) {
new NewsServer();
}
}
When a client connects, the news server sends polling every 30 seconds to maintain the connection.
When a news file is created, the news content is converted into byte and transmitted to the waiting client.
I implemented it as described above, but the connection is frequently lost.
If you have any design problems or have any advice, please let me know. I'm embarrassed about the source of the server socket.
java.net.SocketException: Broken pipe (Write failed)
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
at java.net.SocketOutputStream.write(SocketOutputStream.java:134)
at java.io.DataOutputStream.write(DataOutputStream.java:88)
at com.ns.data.ArticleData.sendPolling(ArticleData.java:272)
at com.ns.NewsServer$PollingThread.run(JNewsServer.java:89)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:750)

Related

Java Socket how to simulate disconection from server

I have a Java program with a client and server sockets, there I want to test that an exception is raised after the server is down.
This is the server:
public class SocketServer implements Runnable {
private bool serverRuns = false;
private int timeout = 10000;
private DataInputStream in;
private DataOutputStream out;
private Socket client;
private ServerSocket server;
private String message = "Ok";
private waitForInstruction = true;
public SocketServer() throws IOException {
ServerSocket server = new ServerSocket(tcpPort,0,ipAdress);
serverRuns = true;
server.setSoTimeout(timeout)
}
private void waitForClient() {
try {
client = server.accept();
client.setSoTimeout(timeout);
in = new DataInputStream(client.getInputStream());
out = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
fail("I/O Error " + e.getMessage());
}
}
public void run() {
waitForClient();
while (serverRuns) {
if (clientSocket.isClosed()) {
waitForClient();
}
try {
while (waitForInstruction == false) {
// Read input message
String inputStreamString = "";
while (in.available() > 0) {
int c = in.read();
inputStreamString += (char) c;
}
out.write(message.getBytes());
System.out.println("Sent bytes: " + out.size());
setWaitForInstruction(true);
}
} catch (IOException E) {
fail("I/O Error " + E.getMessage());
}
}
}
public void closeServerSocket() {
try {
serverRuns = false;
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
void setWaitForInstruction(boolean waitForInstruction) {
this.waitForInstruction = waitForInstruction;
}
public void startServerSocket() {
serverRuns = true;
}
}
This is the client:
public class SocketClient extends Socket {
private InetAddress address;
private short tcpPort;
private DataInputStream in;
private DataOutputStream out;
private static final int timeOut = 10000;
public SocketClient(InetAddress address, short tcpPort) {
this.tcpPort = tcpPort;
this.address = address;
}
public void connect() throws IOException, SocketTimeoutException {
super.connect(new InetSocketAddress(address, tcpPort), timeOut);
}
public void doStuff() throws IOException {
String request = "Ok?";
String InputStreamString = "";
super.setSoTimeout(timeOut);
this.setSoTimeout(timeOut);
out = new DataOutputStream(super.getOutputStream());
in = new DataInputStream(super.getInputStream());
out.writeBytes(requestString);
int c;
do {
if (in.available() > 0) {
c = in.read();
InputStreamString += (char) c;
}
} while (!InputStreamString.equals("Ok"));
System.out.println(InputStreamString);
}
}
I start the server socket thread with:
#BeforeClass
public static void startSocket() throws IOException {
testServer = new SocketServer();
monitor = new Thread(testServer);
monitor.setName("Test Server Thread");
monitor.setDaemon(true);
monitor.start();
}
And the JUnit test is this:
#Before
public void createSocket() throws Exception {
ipAdress = InetAddress.getLocalHost();
SystemConfig.setLoggerConfigFilePath("LoggerConfig.xml");
socketClient = new SocketClient(ipAdress, 5000);
}
#Test
public void checkServerisDown() {
try {
socketClient.connect();
} catch (IOException e) {
fail("IO Error");
}
testServer.closeServerSocket();
monitor.interrupt();
try {
testServer = new SocketServer();
monitor = new Thread(testServer);
monitor.setName(" Test Server Thread");
monitor.setDaemon(true);
// monitor.start();
testServer.startServerSocket();
testServer.setWaitForInstruction(false);
System.out.print("Test (1/1) CHECK SERVER IS DOWN.....\n");
socketClient.doStuff();
System.out.println("NOT OK!");
} catch (IOException e) {
fail("IO Error " + e.getMessage() + " OK");
}
try {
drEstimControlInterface.close();
testServer.getSocket().close();
} catch (IOException e) {
fail("IO Error");
}
}
#AfterClass
public static void closeSocket() throws IOException {
testServer.closeSocket();
}
However the test is not performing as I intended, I thought that this should return an IOException since the server socket has been closed and the thread has been interrupted, but the client socket still gets the answer from the server socket and prints the "NOT OK!". Could anybody tell me why?
You have to close not only ServerSocket but client socket with streams too.
public void closeServerSocket() {
try {
serverRuns = false;
serverSocket.close();
in.close();
out.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}

ServerSocket does not accept new connection/requests from clients

I have a ServerSocket that does not accept new requests from client while there's an ongoing process. I've been debugging this for quite some time now and I don't know where my error is. As far as i'm concerned I've followed all the initialization for creating new threads.
Below is my code:
public class CService
{
boolean decision = false;
public void otherConnect() throws Exception {
synchronized (_SYNC_){
ServerSocket server = new ServerSocket(14344, 1000);
IsoServerBean isoServerBean = new IsoServerBean();
log.info("Waiting for connections...");
byte[] lenbuf = new byte[4];
while(true){
Socket clientSocket = null;
clientSocket = server.accept();
int otherLen = isoServerBean.getOtherHeaderLength();
int size = 352;
byte[] buf = new byte[size];
clientSocket.getInputStream().read(buf);
HexDump.hexDump(buf,1,size);
byte[] targetBuf = new byte[size-2];
System.arraycopy(buf, 4, targetBuf, 0, size-4);
setMyConnectionClient(clientSocket);
new Thread(new CProcessorForClient(targetBuf, clientSocket, 4), "resp").start();
}
}
}
private class CProcessorForClient extends Thread{
private volatile boolean stopFlag;
private volatile boolean stopped;
private byte[] msg;
private Socket clientSocket;
private Socket socket;
private int millis;
private int ctr =0;
CProcessorForClient(byte[] buf, Socket s, int waitMillis) {
stopFlag = false;
stopped = false;
msg = buf;
socket = s;
millis = waitMillis;
}
public void killMe()
{
stopFlag = true;
synchronized (_SYNC_)
{
this.interrupt();
}
}
public boolean killed()
{
return stopped;
}
public void run() {
try {
Thread.sleep(millis);
log.debug("Parsing incoming: [" + new String(msg) + "]");
IsoMessage request = null;
//OMITTED THE PROCESS OF THE CREATION OF ISO TO BE THROWN TO ANOTHER SERVER
msgFactory.print(request);
try {
this.socket = getMyConnection();//Connection to another server
this.clientSocket = getMyConnectionClient();//Connection from client
request.write(socket.getOutputStream(), 0, 0);
int i = 0;
Integer sleepTime = 500;
Integer waitTime = 5000;
decision = true;
while(decision){
i = i + 1;
Thread.sleep(sleepTime);
if (i * sleepTime >= waitTime) {
this.clientSocket.close();
decision = false;
}
}
} catch (IOException ex) {
log.debug("IO Exception encountered: " + ex.getMessage());
} catch (Exception ex) {
java.util.logging.Logger.getLogger(CService.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
} catch (ParseException ex) {
log.error("Error in parsing incoming message:", ex);
log.debug("ex.getMessage: " + ex.getMessage());
} catch (InterruptedException ex) {
log.error("Interrupted!", ex);
} finally{
if (log != null) log.debug("Thread has finished processing txn.");
}
}
}
public static void main(String[] args) throws IOException
{
System.out.println("RANDOM PRINT OUTS");
}
}
I hope someone can help me with this.
EDIT 1: Is it ok if I did not put the ServerSocket initialization in the main method?
EDIT 2: Updated my otherConnect() method and still same result. I transferred all processing of request inside the thread to be created and it still cannot process new request while there is an ongoing process. See below code.
public void otherConnect() throws Exception {
synchronized (_SYNC_){
ServerSocket server = new ServerSocket(14344, 1000);
IsoServerBean isoServerBean = new IsoServerBean();
log.info("Waiting for connections...");
byte[] lenbuf = new byte[4];
while(true){
Socket clientSocket = null;
clientSocket = server.accept();
int size = 352;
byte[] targetBuf = new byte[size-2];
setMyConnectionClient(clientSocket);
new Thread(new CProcessorForClient(targetBuf, clientSocket, 4), "resp").start();
}
}
}
Below is the code for the Thread
private class CProcessorForClient extends Thread{
private volatile boolean stopFlag;
private volatile boolean stopped;
private byte[] msg;
private Socket clientSocket;
private Socket socket;
private int millis;
private int ctr =0;
CProcessorForClient(byte[] buf, Socket s, int waitMillis) {
stopFlag = false;
stopped = false;
msg = buf;
socket = s;
millis = waitMillis;
}
public void killMe()
{
stopFlag = true;
synchronized (_SYNC_)
{
this.interrupt();
}
}
public boolean killed()
{
return stopped;
}
public void run() {
try {
Thread.sleep(millis);
int isoSize = 352;
byte[] buf = new byte[isoSize];
socket.getInputStream().read(buf);
HexDump.hexDump(buf,1,isoSize);
System.arraycopy(buf, 4, msg, 0, isoSize-4);
IsoMessage request = null;
//OMITTED THE PROCESS OF THE CREATION OF ISO TO BE THROWN TO ANOTHER SERVER
msgFactory.print(request);
try {
this.socket = getMyConnection();//Connection to another server
this.clientSocket = getMyConnectionClient();//Connection from client
request.write(socket.getOutputStream(), 0, 0);
int i = 0;
Integer sleepTime = 500;
Integer waitTime = 5000;
decision = true;
while(decision){
i = i + 1;
Thread.sleep(sleepTime);
if (i * sleepTime >= waitTime) {
this.clientSocket.close();
decision = false;
}
}
} catch (IOException ex) {
log.debug("IO Exception encountered: " + ex.getMessage());
} catch (Exception ex) {
java.util.logging.Logger.getLogger(CService.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
} catch (ParseException ex) {
log.error("Error in parsing incoming message:", ex);
log.debug("ex.getMessage: " + ex.getMessage());
} catch (InterruptedException ex) {
log.error("Interrupted!", ex);
} finally{
if (log != null) log.debug("Thread has finished processing txn.");
}
}
}

java.net.SocketException: Connection reset when trying to pass an object from a client to a server

I am trying to pass an object through the ObjectOutputStream class through the client, and receive it through ObjectInputStream, the problem is that the java.net.SocketException: Connection reset error appears, eliminating this past of objects between client and server, the problem is It solves, but I do not know what the error would be.
Before I worked correctly when I had the client code on the server and vice versa, but now that I change these parts of the code does not want to work. In these lines is where this error jumps, on module server:
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Computer c = (Computer) ois.readObject();
CLIENT
private void startClient() {
DataInputStream in = null;
DataOutputStream out = null;
Socket socket = null;
try {
socket = new Socket(ip, port);
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
//MANDAMOS EL NUMERO EN RANGO HACIA LOS SERVIDORES
out.writeInt(n);
out.flush();
//LEEMOS EL TIEMPO ENVIADO POR EL SERVIDOR
tiempo = in.readLong();
System.out.println(tiempo);
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Computer c = (Computer) ois.readObject();
synchronized (main) {
main.add(c);
}
ois.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
out.close();
in.close();
socket.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
SERVER
private void startServer(){
DataOutputStream out = null;
DataInputStream in = null;
ServerSocket ss = null;
try {
Socket socket = null;
ss = new ServerSocket(port);
System.out.println("Esperando conexion");
socket = ss.accept();
in = new DataInputStream(socket.getInputStream());
int n = in.readInt();
long time = encontrarPrimos(n);
out = new DataOutputStream(socket.getOutputStream());
out.writeLong(time);
out.flush();
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
Computer c = new Computer(id, Computer.getLocalIp(), time, Computer.getUserDomainSO());
oos.writeObject(c);
oos.close();
in.close();
out.close();
socket.close();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
} finally {
}
}
COMPUTER CLASS
public class Computer implements Serializable{
private int id;
private String ip;
private long time;
private String userDomain;
public Computer(int id, String ip, long time, String userDomain) {
this.id = id;
this.ip = ip;
this.time = time;
this.userDomain = userDomain;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public String getUserDomain() {
return userDomain;
}
public void setUserDomain(String userDomain) {
this.userDomain = userDomain;
}
#Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + this.id;
hash = 59 * hash + Objects.hashCode(this.ip);
hash = 59 * hash + (int) (this.time ^ (this.time >>> 32));
hash = 59 * hash + Objects.hashCode(this.userDomain);
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Computer other = (Computer) obj;
if (this.id != other.id) {
return false;
}
if (this.time != other.time) {
return false;
}
if (!Objects.equals(this.ip, other.ip)) {
return false;
}
if (!Objects.equals(this.userDomain, other.userDomain)) {
return false;
}
return true;
}
#Override
public String toString() {
return "Computer{" + "id=" + id + ", ip=" + ip + ", time=" + time + ", userDomain=" + userDomain + '}';
}
public static String getLocalIp(){
try {
InetAddress localhost = InetAddress.getLocalHost();
return localhost.getHostAddress().trim();
} catch (UnknownHostException ex) {
Logger.getLogger(Computer.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public static String getUserDomainSO() {
String operatingSystem = System.getProperty("os.name");
if ("Linux".equals(operatingSystem) || "Mac OS X".equals(operatingSystem)) {
return System.getProperty("user.name");
} else if ("Windows".equals(operatingSystem)) {
return System.getenv("USERDOMAIN");
} else {
throw new RuntimeException("Unsupported operating system.");
}
}
}
The error is the next:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:210)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2663)
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2679)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:3156)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:862)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:358)
at Client.startClient(Client.java:71)
at Client.run(Client.java:44)
at java.lang.Thread.run(Thread.java:748)
I made few modifications to your client code and it is working. I am not using Computer object here. Instead, I have used String cast.
private void startClient() {
DataInputStream in = null;
DataOutputStream out = null;
Socket socket = null;
try {
InetAddress host = InetAddress.getLocalHost();
socket = new Socket(host.getHostName(), 9876);
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
//MANDAMOS EL NUMERO EN RANGO HACIA LOS SERVIDORES
out.writeInt(1000);
out.flush();
//LEEMOS EL TIEMPO ENVIADO POR EL SERVIDOR
long tiempo = in.readLong();
System.out.println(tiempo);
String str;
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
if ((str = (String) ois.readObject()) != null) {
System.out.println(str);
}
ois.close();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} finally {
try {
out.close();
in.close();
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
After testing different solutions, the main error was not the code, but the JVM installed on the computer where the client was running, so the solution was to install Java from 0, using the same version that was previously installed.

Discovering Local Network Devices & IPs Programmaticaly

I'm trying to make a project that must make me able to find local devices in same network and information regarding their IPs,mac addresses and vendors.Everything is good so far but question is I relaized that by this code ,it only discovers to mobile phones and somehow doesnt see my laptops ? I tested this code and it only shows my tablet and phones but no computers.If u have any suggestion pls let me now.Thanks in advance.And here is my code belove.
//This class is my pinger class
public class DiscoverRunner implements Runnable {
private List<InetAddress> results;
private String subnet;
private Integer startAdd;
private Integer numAdds;
public DiscoverRunner(String subnet, Integer start, Integer steps) {
this.subnet = subnet;
this.startAdd = start;
this.numAdds = steps;
results = new LinkedList<InetAddress>();
}
#Override
public void run() {
int timeout=4000;
for (int i=startAdd;i<startAdd+numAdds;i++){
String host=subnet +"." + i;
try {
InetAddress a = InetAddress.getByName(host);
if (a.isReachable(timeout)){
results.add(a);
//System.out.println(host + " is reachable");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public List<InetAddress> getResults(){
return results;
}
}
And here is my another class where i Handle threads to execute
public class Pinger {
private static final int NUMTHREADS = 254;
public static String myMacAddress = "";
public static ArrayList<Device> getDevicesOnNetwork(String subnet) throws IOException {
LinkedList<InetAddress> resAddresses = new LinkedList<InetAddress>();
DiscoverRunner[] tasks = new DiscoverRunner[NUMTHREADS];
Thread[] threads = new Thread[NUMTHREADS];
//Create Tasks and treads
for (int i = 0; i < NUMTHREADS; i++) {
tasks[i] = new DiscoverRunner(subnet,i,1);
threads[i] = new Thread(tasks[i]);
}
//Starts threads
for (int i = 0; i < NUMTHREADS; i++) {
threads[i].start();
}
for (int i = 0; i < NUMTHREADS; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < NUMTHREADS; i++) {
for (InetAddress a : tasks[i].getResults()) {
try {
a = InetAddress.getByName(a.getHostAddress());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
resAddresses.add(a);
}
}
ArrayList<Device> foundDev = new ArrayList<Device>(resAddresses.size());
for (InetAddress a : resAddresses) {
foundDev.add(new Device(a.getHostAddress(), getMacFromArpCache(a.getHostAddress()), a.getCanonicalHostName(), getVendorName(getMacFromArpCache(a.getHostAddress()))));
}
return foundDev;
}
/**
* Try to extract a hardware MAC address from a given IP address using the
* ARP cache (/proc/net/arp).<br>
* <br>
* We assume that the file has this structure:<br>
* <br>
* IP address HW type Flags HW address Mask Device
* 192.168.18.11 0x1 0x2 00:04:20:06:55:1a * eth0
* 192.168.18.36 0x1 0x2 00:22:43:ab:2a:5b * eth0
*
* #param ip
* #return the MAC from the ARP cache
*/
public static String getMacFromArpCache(String ip) {
if (ip == null) {
return null;
}
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("/proc/net/arp"));
String line;
while ((line = br.readLine()) != null) {
String[] splitted = line.split(" +");
if (splitted != null && splitted.length >= 4 && ip.equals(splitted[0])) {
// Basic sanity check
String mac = splitted[3];
if (mac.matches("..:..:..:..:..:..")) {
return mac;
} else {
return null;
}
}
}
return myMacAddress;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
public static String getVendorName(String MacAddress) throws IOException {
try {
URL url = new URL("http://api.macvendors.com/" + MacAddress);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
InputStream in = new BufferedInputStream(conn.getInputStream());
String vendorName = org.apache.commons.io.IOUtils.toString(in, "UTF-8");
return vendorName;
} catch (MalformedURLException e) {
return null;
} catch (ProtocolException e) {
return null;
} catch (IOException e) {
return null;
}
}
}
this ping as you do on command line, maybe you can change your coding style.
try {
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("ping 192.168.0.142");
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
System.out.println(line);
p.destroy();
break;
}
input.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

print BufferedReader while Socket remains open

What I want are just the responses from wunderground printed to the console:
public class Weather {
public static void main(String[] args) {
String host = "rainmaker.wunderground.com";
int port = 3000;
int c;
{
try (Socket socket = new Socket(host, port);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in))) {
while (true) {
System.out.println(socket.toString());
c = bufferedReader.read();
System.out.print((char) c);
}
} catch (IOException ex) {
System.out.println(ex + host + port);
System.exit(1);
} finally {
System.exit(1);
}
}
}
}
However, there's not much output to go on:
thufir#dur:~/NetBeansProjects/MudSocketClient$
thufir#dur:~/NetBeansProjects/MudSocketClient$ java -jar dist/MudSocketClient.jar
Socket[addr=rainmaker.wunderground.com/38.102.137.140,port=3000,localport=53550]
^Cthufir#dur:~/NetBeansProjects/MudSocketClient$
thufir#dur:~/NetBeansProjects/MudSocketClient$
Running telnet from the CLI, the connection works fine.
I found some old code:
public class InputOutput extends Observable {
private static final Logger log = Logger.getLogger(InputOutput.class.getName());
private Alias alias = new Alias();
public InputOutput() {
}
private void readFromConsole(final OutputStream outputStream) {
Thread read = new Thread() {
#Override
public void run() {
String line;
byte[] bytes;
Scanner scanner;
while (true) {
GameDataBean gameData = null;
scanner = new Scanner(System.in);
line = scanner.nextLine();
try {
gameData = alias.parseUserInput(line);
} catch (StringIndexOutOfBoundsException e) {
log.fine(e.toString());
}
if (gameData != null) {
setChanged();
notifyObservers(gameData);
} else {
bytes = line.getBytes();
try {
outputStream.write(bytes);
outputStream.write(10);
outputStream.flush();
} catch (IOException ex) {
log.fine(ex.toString());
}
}
}
}
};
read.start();
}
private void readInput(final InputStream inputStream) throws FileNotFoundException, IOException {
Thread readInput = new Thread() {
#Override
public void run() {
char ch = 0;
int intVal = 0;
StringBuilder sb = new StringBuilder();
try {
while ((intVal = inputStream.read()) != -1) {
ch = (char) intVal;
printToConsole(ch);
//logToFile(ch);
sb.append(ch);
if (intVal == 13) {
setChanged();
notifyObservers(sb.toString());
sb = new StringBuilder();
}
}
} catch (IOException ex) {
Logger.getLogger(InputOutput.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void logToFile(char c) throws IOException {
String fname = "weather.log";
File f = new File(fname);
f.createNewFile();
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(fname, true)))) {
out.print(c);
out.flush();
}
}
private void printToConsole(char c) {
System.out.print(c);
}
};
readInput.start();
}
public void readWriteParse(final InputStream inputStream, final OutputStream outputStream) throws FileNotFoundException, IOException {
readFromConsole(outputStream);
readInput(inputStream);
}
}
I think it's that, when the socket is still open, it has to be multi-threaded, as I recall.

Categories