Today I was trying to write some, lets say, internet communicator.
I'm learning basics of Java (from instructables) and now it's time for network programming.
What I want my program to do:
If there is any data on input stream from network - get data, put it into string and print in a console.
If there is data in console - put it into string and send it by network.
When I try only send data from client app to server and print it in server console - everything works fine. But then I have different code (without getting and sending data two way).
I know that problem is in lines inside while(true) statements in line if(cin.hasNextLine()). I don't understand why it blocks whole app when it should be just returning false or true if there isn't or there is data in console (from keyboard).
The annoying is that it's working perfectly with reading files.
Oh. And also I tried to check IF data which I didn't typed into console is "". It didn't solved my problem.
Server code:
import java.net.*;
import java.io.*;
import java.util.*;
import java.time.LocalTime;
public class GreetingServer extends Thread {
private ServerSocket serverSocket;
public GreetingServer(int port) throws IOException {
serverSocket = new ServerSocket(port, 0);
serverSocket.setSoTimeout(30000);
}
public void run() {
while(true) {
try {
System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to " + server.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(server.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress());
FileWriter plik = new FileWriter("/home/greg/Dokumenty/logizserwera.txt", true);
System.out.println("StartTime: " + LocalTime.now());
Scanner cin = new Scanner(System.in);
String stringReadyToSend, stringGotFromClient = null;
while(true) {
System.out.println("Before hasnextline");
if(cin.hasNextLine()) {
stringReadyToSend = cin.nextLine();
out.writeUTF(stringReadyToSend);
}
if(in.available() != 0) {
stringGotFromClient = in.readUTF();
// EOT means End Of Transmission
if(stringGotFromClient.equals("EOT")) break;
else System.out.println("Message from client: " + stringGotFromClient();
}
else System.out.println("No message");
break;
}
System.out.println("EndTime: " + LocalTime.now());
server.close();
plik.close();
}
catch(SocketTimeoutException s) {
System.out.println("Socket timed out!");
break;
}
catch(IOException e) {
e.printStackTrace();
break;
}
}
}
public static void main(String[] args) {
int port = 6066;
try {
Thread t = new GreetingServer(port);
t.start();
}catch(IOException e) {
e.printStackTrace();
}
}
}
And client code:
import java.net.*;
import java.io.*;
import java.util.*;
public class GreetingClient {
public static void main(String[] args) {
String serverName = "localhost";
Scanner cin = new Scanner(System.in);
int port = 6066;
try {
System.out.println("Connecting to " + serverName + " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to " + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF("Hello from " + client.getLocalSocketAddress());
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
String lineReadyToSend, lineGotFromServer;
while(cin.hasNextLine()) {
if(cin.hasNextLine()) {
// EOT means End Of Transmission
lineReadyToSend = cin.nextLine();
if(lineReadyToSend.equals("EOT")) {
out.writeUTF(lineReadyToSend);
break;
}
else out.writeUTF(lineReadyToSend);
}
if(in.available() != 0) {
lineGotFromServer = in.readUTF();
System.out.println("Message from server: " + lineGotFromServer);
}
}
out.writeUTF("EOT");
client.close();
System.out.println("End of transmission. Server disconnected");
}catch(IOException e) {
e.printStackTrace();
}
}
}
You are using cin which is a Scanner for the System.in
Practically that just scans if there are entered lines on the console. Perhaps try doing that with the data input stream (in) on your server.
Well, everything looks god. Just a cuestion, do you execute both applications at same time? Well, if it's the case, could be the access to System.in resource. Remember this is a static field, and not instantiated. Try to run one of them in other location. A second hint: use try clause and watch the errors if there are, and use debuging or resource monitor tools to detect the problem.
Related
I was given the below code by my teacher for a class. I ran it one or twice and it worked fine. However I suddenly cannot get it to run from the command prompt on Windows 8 anymore. No matter what port I specify it just prints "Opening port..." and never continues. No exception is ever thrown. I have disabled my firewall and antivirus and it does not seem to work. I have added a print statement as the first line of the try catch block and it will print but it just will not create the new Socket. I am sure it is something in my Windows settings but I am unsure as to what or how to resolve it.
// Server program
// File name: "TCPServer.java"
import java.io.*;
import java.net.*;
public class TCPServer
{
private static ServerSocket servSock;
public static void main(String[] args)
{
System.out.println("Opening port...\n");
try{
// Create a server object
servSock = new ServerSocket(Integer.parseInt(args[0]));
}
catch(IOException e){
System.out.println("Unable to attach to port!");
System.exit(1);
}
do
{
run();
}while (true);
}
private static void run()
{
Socket link = null;
try{
// Put the server into a waiting state
link = servSock.accept();
// Set up input and output streams for socket
BufferedReader in = new BufferedReader(new InputStreamReader(link.getInputStream()));
PrintWriter out = new PrintWriter(link.getOutputStream(),true);
// print local host name
String host = InetAddress.getLocalHost().getHostName();
System.out.println("Client has estabished a connection to " + host);
// Receive and process the incoming data
int numMessages = 0;
String message = in.readLine();
while (!message.equals("DONE"))
{
System.out.println(message);
numMessages ++;
message = in.readLine();
}
// Send a report back and close the connection
out.println("Server received " + numMessages + " messages");
}
catch(IOException e){
e.printStackTrace();
}
finally{
try{
System.out.println("!!!!! Closing connection... !!!!!\n" + "!!! Waiting for the next connection... !!!");
link.close();
}
catch(IOException e){
System.out.println("Unable to disconnect!");
System.exit(1);
}
}
}
}
This code works fine. The problem is the code for the client. The answer to your problem is already written in a comment in your code.
// Put the server into a waiting state
link = servSock.accept();
The server goes into a waiting state until it gets a connection. The client is the one that would be getting the error since it did not connect. If the client was working correctly the code would continue and you would get the additional output.
I am new to sockets in JAVA. Recently, I am trying to build a server-client program that clients can search a word from the dictionary in server side and the server will return the defintion of the word to the clients. The code in server side is as the following:
public class DictionaryServer {
private static int port;
private static String dicFile;
static Map<String, String> dictionary = new HashMap<String, String>();
int userCounter = 0;
public static void main(String[] args) {
//check if starting the server in valid format
if (args.length != 2) {
System.err.println("Invalid format to start DictionaryServer");
System.err.println("Usage: java DictionaryServer <port number> <the name of dictionary>");
System.exit(1);
}
port = Integer.parseInt(args[0]);
dicFile = args[1];
try{
System.out.println("IP: " + InetAddress.getLocalHost());
System.out.println("port: " + port);
}
catch(UnknownHostException e){
e.printStackTrace();
}
DictionaryServer s = new DictionaryServer();
s.server(port, dicFile);
}
public void server(int port, String dicFile) {
ServerSocketFactory serverSocket = ServerSocketFactory.getDefault();
try(ServerSocket server = serverSocket.createServerSocket(port)){
System.out.println("Server IP: " + server.getInetAddress());
System.out.println("Listening for client connections...");
while(true){
Socket client = server.accept();
System.out.println("Client \"" + client.getRemoteSocketAddress().toString()
+ "\""+ " is connecting.");
Thread t = new Thread(() -> service(client, dicFile));
t.start();
}
}
catch (UnknownHostException e) {
e.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}
}
public void service(Socket client, String dicFile){
try(Socket clientSocket = client){
// Input and Output stream of the client
DataInputStream input = new DataInputStream(
clientSocket.getInputStream());
DataOutputStream output = new DataOutputStream(
clientSocket.getOutputStream());
//check request
int action = input.readInt(); //1:add, 2:remove, 3:query
String word = input.readUTF();
//choose action
Dic d = new Dic(dicFile);
switch(action){
case 1: //add
String definition = input.readUTF();
output.writeUTF(d.add(word, definition, dicFile));
break;
case 2: //remove
output.writeUTF(d.remove(word, dicFile));
break;
case 3: //query
output.writeUTF(d.query(word, dicFile));
break;
}
}
catch(IOException e){
String message=e.getMessage();
System.out.println(message);
System.out.println();
}
}
I am got stucked in an error when I try to restart the serverprogram: java.net.BindException: Address already in use (Bind failed)
For example, last time I execute the server program with the port 4000 and it worked, but if I want to execute the server program with the same port again, the exception will show up. I checked what the port 4000 is doing by "lsof -i:4000" in terminal which told me:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 19683 Andy 7u IPv6 0x43e8f876eb74b731 0t0 TCP *:terabase (LISTEN)
Does anyone know how I can fix this problem? Thank you!
You need make sure your program has really exited, and you also need to set reuseAddress. To do that you have to create the server socket without binding, set the option, and then bind it, in three different steps:
ServerSocket server = serverSocketFactory.createServerSocket();
server.setReuseAddress(true);
server.bind(new InetSocketAddress(port));
I'm writing a simple client-server application using TCP Sockets . It works with the multi-threading principle to allow for several client connections to the same server.
I'm having some trouble figuring out some of the errors I get with the sockets, i'm fairly new in this environment as you will probably tell.
I'll show you the code I have, and the output i get from it, but basically the problem lies in the very connecting of the clients to the server, and I ran through all the code but still can't find what's wrong with it.
Server:
public static ArrayList<String> userList = new ArrayList<String>();
public static int index;
public static String date;
public static void main(String args[]) throws Exception {//inicio main
ServerSocket server = new ServerSocket(6500); //Create socket on port 6500
System.out.println ("Server started on port 6500");
while (true){ //Waiting for clients
System.out.println("Server waiting for client connections..");
Socket socket = null;
BufferedReader reader = new BufferedReader(new FileReader("C:\\UNIV\\Redes\\workspace\\Copy of Ex_4.3_Teste\\lists\\blacklist.txt"));
String line = null;
socket = server.accept();
// Blacklist verification
while ((line = reader.readLine()) != null) {
if (line.equals(socket.getInetAddress().toString())) {
System.out.println("IP Blacklisted: " + socket.getInetAddress().toString());
System.out.println("Closing connection to " + socket.getInetAddress().toString());
PrintStream checkBlack = new PrintStream(socket.getOutputStream(),true);
checkBlack.println("***BLACKLISTED***");
reader.close();
checkBlack.close();
socket.close();
break;
}
}//End of Blacklist Verification
//Sending feedback in case of approved client
try {
PrintStream checkBlack = new PrintStream(socket.getOutputStream(),true);
checkBlack.println("***NBLACKLISTED***");
checkBlack.close();
} catch (SocketException e) {
}
userList.add(socket.getInetAddress().toString()); //Add connected user's IP to USERLIST
System.out.println("New connection..");
System.out.println("Size of UserList: " + userList.size());
Thread t = new Thread(new EchoClientThread(socket));
t.start(); //Starting Client Thread
}//End of Waiting for Clients
}//End of Main
public static class EchoClientThread implements Runnable{
private Socket s;
public EchoClientThread(Socket socket) {
this.s = socket;
}
public void run() {
String threadName = Thread.currentThread().getName(); //Thread Name
String stringClient = s.getInetAddress().toString(); //Client IP
System.out.println("Connected to " + stringClient);
try{
BufferedReader input = new BufferedReader(
new InputStreamReader(s.getInputStream()));
PrintStream output = new PrintStream(
s.getOutputStream(),true);
String line;
while ((line = input.readLine()) !=null) { //Input Cycle
System.out.println (stringClient+": "+threadName+": "+line); //Print command from client
if (line.equalsIgnoreCase("9")){ //Exit
break;
}
else if (line.equalsIgnoreCase("1")){ //Send List of Online Users
System.out.println("Option 1: Sending list of online users to " + stringClient);
output.println(" ");
output.println("List of Online Users:");
output.println(" ");
for(int i=0;i<userList.size();i++){
output.println(userList.get(i));
}
}
else if (line.equalsIgnoreCase("2")) { //Send message to a single user
System.out.println("Nothing here yet..");
}
else if (line.equalsIgnoreCase("3")) { //Send message to all the online users
System.out.println("Nothing here yet..");
}
else if (line.equalsIgnoreCase("4")){ //Send User Blacklist
System.out.println("Option 4: Sending user blacklist to " + stringClient);
BufferedReader reader = new BufferedReader(new FileReader("C:\\UNIV\\Redes\\workspace\\Copy of Ex_4.3_Teste\\lists\\blacklist.txt"));
String lineRead = null;
output.println(" ");
output.println("User Blacklist:");
output.println(" ");
while ((lineRead = reader.readLine()) != null) {
output.println(lineRead);
}
reader.close();
}
else{
output.println("Unknown command.");
}
output.println("***CLOSE***"); //Closes client's input cycle
output.println("***NBLACKLISTED***"); //Sending feedback in case of approved client
}//Input Cycle End
output.println("See you later!");
input.close(); //Closes inputStream
output.close(); //Closes outputStream
s.close(); //Closes Socket
}
catch (Exception e){
System.err.println("Server Side Error!");
System.out.println(e);
}
userList.remove(s.getInetAddress().toString());
System.out.println("Client "+ stringClient+" was disconnected!");
}//End of run()
}//End of EchoClientThread
}//End of EchoServerThread
Client:
public static void main(String args[]) throws Exception {
if (args.length !=1){
System.err.println ("usage: java EchoClient2 <host>");
System.exit(1);
}
String host = args[0];
int port = 6500;
String cmd, line;
Socket socket = new Socket(host,port);
BufferedReader input = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintStream output = new PrintStream(socket.getOutputStream(),true);
while( true ) {//Input cycle
Scanner scan = new Scanner (System.in);
if (input.readLine().equals("***BLACKLISTED***")) {
System.out.println("IP is Blacklisted");
break;
}
System.out.println(" ");
System.out.println("CLIENT MENU");
System.out.println(" ");
System.out.println("1 - List on-line users");
System.out.println("2 - Send message to a single user");
System.out.println("3 - Send message to all on-line users");
System.out.println("4 - List Blacklisted Users");
System.out.println("9 - Exit");
System.out.println(" ");
System.out.print(host+":"+port+"#>"); //Command prompt
cmd = scan.nextLine(); //Scanning command to send to the server
output.println(cmd); //Sending command to the server
if ( cmd.equalsIgnoreCase("9")){
System.out.println("Exiting..");
break;
}
try {
while (!(line = input.readLine()).equals("***CLOSE***")) { //Input Cycle
System.out.println (line); //Prints server answer
}
} catch (Exception e) {
System.err.println("Client Side Error!");
System.out.println(e);
break;
}
}//End of Cycle
System.out.println("Connection Terminated");
input.close(); //Closes inputStream
output.close(); //Closes outputStream
socket.close(); //Closes Socket
}
}
So the server starts fine with the following output:
Server started on port 6500
Server waiting for client connections..
But as soon as I try to connect with the client, this happens:
Server Side:
Server started on port 6500
Server waiting for client connections..
New connection..
Size of UserList: 1
Server waiting for client connections..
Connected to /127.0.0.1
java.net.SocketException: Socket is closed
Server Side Error!
Client /127.0.0.1 was disconnected!
On the client side, though, it still shows the input menu, and the command prompt, like so:
CLIENT MENU
1 - List on-line users
2 - Send message to a single user
3 - Send message to all on-line users
4 - List Blacklisted Users
9 - Exit
127.0.0.1:6500#>
And when I input something on the Client Side prompt, i get:
127.0.0.1:6500#>1
Client Side Error!
java.net.SocketException: Software caused connection abort: recv failed
Connection Terminated
I know what the errors mean, Socket is closed is pretty much self-explanatory, but i just can't find wheres the code problem that makes the socket close.
Any help is much appreciated.
You have your blacklist mechanism not quite right.
When you close a stream associated with the socket it will close the socket as well.
So the server is closing any socket that it gets and then hands it on to a thread,
which tries to use the socket and fails.
// Blacklist verification
while ((line = reader.readLine()) != null) {
// blah blah blah
}//End of Blacklist Verification
//Sending feedback in case of approved client
try {
PrintStream checkBlack = new PrintStream(socket.getOutputStream(),true);
checkBlack.println("***NBLACKLISTED***");
checkBlack.close(); // <== why are you closing the stream?
} catch (SocketException e) {
}
try this instead
// Blacklist verification
while ((line = reader.readLine()) != null) {
// blah blah blah
}//End of Blacklist Verification
//Sending feedback in case of approved client
try {
socket.getOutputStream().write("***NBLACKLISTED***\n".getBytes());
} catch (SocketException e) {
e.printStackTrace();
}
A debugger is your friend.
I've connected to an already existent server that contains lines of strings I need to read in. Given that I only need to read in a String type, which input reader would work here so I could read line by line in my While loop? Here's my simple Client:
public class Client
{
public static final int PORT_NUMBER = 8888;
public static void main(String[] args)
{
int port = PORT_NUMBER;
String content;
OutputStream output;
InputStream input;
Socket s = null;
try
{
s = new Socket("server.example.exp", port);
output = s.getOutputStream();
input = s.getInputStream();
System.out.println("Connected to " + s.getInetAddress() + " on port " + s.getPort());
}
catch (IOException e) {System.err.println(e);}
while (true)
{
try
{
//read next line from server
}
catch (EOFException eof){
System.out.println("eof encountered" + eof.getMessage());
break;
}
catch (OptionalDataException ode){System.out.println("OptionalDataException" + ode.getMessage());}
catch (IOException ioe){System.out.println("IOException on read object");}
catch (ClassNotFoundException cnf){System.out.println("ClassNotFoundException");}
}
}
}
I know it's a very basic question, I'm just having trouble getting started, is all. I appreciate any clarification. Thanks.
To read from an InputStream, you can wrap it in a InputStreamReader, and then a BufferedReader, from which you can readLine:
BufferedReader input;
input = new BufferedReader(new InputStreamReader(s.getInputStream()));
Then:
while(true){
try{
input.readLine();//Read from server
}
Add the folloWing line before your while
BufferedReader inp2 = new BufferedReader(new InputStreamReader(inp));
while (true) {
try {
inp2.readLine();
}
}
i'm new to programming and I'm trying to build a blackberry IRC Client, I made it connect to a server, join a channel and say something, but how can I receive messages ? I don't know how to make a loop to wait for messages, can somebody help me ? here is my code:
package com.rim.samples.device.socketdemo;
import java.io.*;
import javax.microedition.io.*;
import net.rim.device.api.ui.*;
public class ConnectThread extends Thread
{
private InputStream _in;
private OutputStreamWriter _out;
private SocketDemoScreen _screen;
// Constructor
public ConnectThread()
{
_screen = ((SocketDemo)UiApplication.getUiApplication()).getScreen();
}
public void run()
{
StreamConnection connection = null;
String user = "Cegooow";
String channel = "#oi";
try
{
_screen.updateDisplay("Opening Connection...");
String url = "socket://" + _screen.getHostFieldText() + ":6667" + (_screen.isDirectTCP() ? ";deviceside=true" : "");
connection = (StreamConnection)Connector.open(url);
_screen.updateDisplay("Connection open");
_in = connection.openInputStream();
_out = new OutputStreamWriter(connection.openOutputStream());
StringBuffer s = new StringBuffer();
_out.write("NICK " + _screen.getNickText() + "\r\n");
_out.write("USER " + user + "8 * : Java Bot\r\n");
_out.write("JOIN " + channel + "\r\n");
_out.write("PRIVMSG " + channel + " " + _screen.getMessageFieldText() + "\r\n");
_screen.updateDisplay("Done!");
}
catch(IOException e)
{
System.err.println(e.toString());
}
finally
{
_screen.setThreadRunning(false);
try
{
_in.close();
}
catch(IOException ioe)
{
}
try
{
_out.close();
}
catch(IOException ioe)
{
}
try
{
connection.close();
}
catch(IOException ioe)
{
}
}
}
}
I used the sockets demo sample on blackerry jre, thanks
In your code you have an OutputStreamWriter _out to write to the Server, the incoming connection _in (InputStream) is unused. You should expect any incoming data there...
The simplest example I can think of would be like this:
// process the inputstream after writing to _out - in single threaded app
Reader reader = new InputStreamReader(_in);
int data;
while((data = reader.read()) != -1 ){
System.out.println((char) data); // do something with the char
}
reader.close();
In practice, it would be better to use a BufferedReader. Also, if you are building a chat application it might be beneficial to create a new thread to process incoming data and another thread for outgoing data.
Once you get your input stream reader handle you can loop until connection closes
BufferedReader reader = new BufferedReader(_in);
while(true) {
String line = reader.readLine();
// do something...
}