I'm new to java socket programming, I'm making a client server program. the server is multithreaded.
when the client connection with server is open. the server sends a text block to the client like this:
connection is open with the server....
Welcome Please Chose one of the following Operations
Insert, Read, Update, Delete
Type Exit to terminate connection.
when I type read or exit or any of the operations it works fine and the server responds.
but the problem happens when I chose an operation i.e insert --> when the server responds and asks me for input and I wanna insert a value, the program keeps taking input infinitely for endless lines I don't know where the problem and how it happens.
it's the same code, the client sends the input as one line when choosing operation but when I chose insert operation and the server is expecting a value it takes it as infinite endless lines.
Client class
public class Client1 {
public static void main(String[] args) throws IOException {
Socket socket=null;
try {
System.out.println("sending connection request to host 127.0.0.1 at port 2000");
socket = new Socket("127.0.0.1", 2000);
System.out.println("connection is open with the server....");
Scanner scn = new Scanner(System.in);
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
DataInputStream dis = new DataInputStream(socket.getInputStream());
while (true) {
System.out.println(dis.readUTF());
String tosend = scn.nextLine();
dos.writeUTF(tosend);
// If client sends exit,close this connection
// and then break from the while loop
if (tosend.equals("Exit")) {
System.out.println("Closing this connection : " + socket);
socket.close();
System.out.println("Connection closed");
break;
}
String received = dis.readUTF();
System.out.println(received);
}
// closing resources
scn.close();
dis.close();
dos.close();
}
catch (Exception e ){
System.out.println(e);
} finally {
try {
if (socket != null) socket.close();
} catch (Exception e){
System.out.println(e);
}
}
}
Server Class
public class ServerThread extends Thread{
Socket socket ;
DataInputStream dis;
DataOutputStream dos;
ServerThread(Socket socket,DataInputStream dis,DataOutputStream dos ){
this.socket = socket;
this.dis=dis;
this.dos=dos;
}
#Override
public void run(){
String received;
String toreturn;
String welcomeText = """
Welcome Please Chose one of the following Operations
Insert, Read, Update, Delete
Type Exit to terminate connection.""";
while (true){
try {
// Ask user what he wants
dos.writeUTF(welcomeText);
// receive the answer from client
received = dis.readUTF();
if(received.equals("Exit"))
{
System.out.println("Client " + this.socket + " sends exit...");
System.out.println("Closing this connection.");
this.socket.close();
System.out.println("Connection closed");
break;
}
// write on output stream based on the
// answer from the client
switch (received) {
// the problem starts here if I chose insert and wanna print what the user typed, it takes
//input infinitely from the user
case "Insert":
toreturn = "Inserting new info...";
dos.writeUTF(toreturn);
String out = dis.readUTF();
dos.writeUTF("Accepted");
dos.writeUTF(out);
break;
case "Read":
toreturn = "Reading User Info...";
dos.writeUTF(toreturn);
break;
case "Update":
toreturn = "Updating User Info...";
dos.writeUTF(toreturn);
break;
case "Delete":
toreturn = "Deleting User Info";
dos.writeUTF(toreturn);
break;
default:
dos.writeUTF("Unknown User");
break;
}
} catch ( IOException e) {
e.printStackTrace();
}
}
try
{
// closing resources
this.dis.close();
this.dos.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
I don't know how this loop happens especially since the server accepts input correctly when choosing operations but when insert operation is chosen it just takes input infinitely, can anyone help please, i cant implement any operation if this problem persists.
I think its your Client, in the while loop try to remove the second read from server, it's because you once read all what server sents, and when the loop starts again wants to read from server but there is nothing to read and becomes idle.
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'm trying to send a command and have it execute through a socket connection. I need to read each response line, then continue sending commands to the same process. Below I have the methods that handle that.
Currently, I receive a response when I initially open the socket connection, but after, the program hangs until the foreign host closes the connection, presumably because no input was entered in a specified amount of time.
public static void main(String[] args) {
try {
sendSmtpTest("anEmail#aRandomDomain");
} catch (Exception e) {
e.printStackTrace();
}
}
public static boolean sendSmtpTest(String address) throws Exception {
Socket socket = new Socket("a.random.address", 0000);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
int res;
System.out.println("1");
System.out.println(in.readLine());
System.out.println("2");
System.out.println(in.readLine());
say(out, "HELO netatlantic.com");
System.out.println("3");
System.out.println(in.readLine());
System.out.println("4");
System.out.println(in.readLine());
say(out, "MAIL FROM: <abuse#netatlantic.com>");
System.out.println("5");
System.out.println(in.readLine());
say(out, "RCTP TO: <" + address + ">");
System.out.println("6");
System.out.println(in.readLine());
say(out, "RSET");
System.out.println("7");
say(out, "QUIT");
// clean up
in.close();
in.close();
out.close();
return true;
}
private static void say(BufferedWriter wr, String text) throws IOException {
wr.write((text + "\r\n"));
wr.newLine();
wr.flush();
}
The random printing of the numbers are a way for me to know where in the program it is at. Also, I have to run this off of a server, thus I cannot run it in a debugger because the socket I'm connecting to only accepts connections from a specific address.
Thanks!
You mean that you see the 220 status from the SMTP server print out, but then it just hangs?
That's because you are waiting for another line to be sent from the server, but it's waiting for your HELO command. (Right after your "2" statement.) Remove that extra System.out.println(in.readLine()); and see if you make progress.
If not, post the output from your program so that your question is more understandable.
I have a 2 nodes that should always communicate with each other, but they don't seem to talk for more than 1 interaction. After successfully sending and receiving 1 message, they stop.
My code looks like this:
The initiator:
try {
Socket client = new Socket(ip, port);
OutputStream toNode = client.getOutputStream();
DataOutputStream out = new DataOutputStream(toNode);
out.writeUTF("Start:Message");
System.out.println("Sent data");
InputStream fromNode = client.getInputStream();
DataInputStream in = new DataInputStream(fromNode);
if(in.readUTF().equals("Return Message")) {
System.out.println("Received data");
out.writeUTF("Main:Message");
System.out.println("Sent data again");
}
else
System.out.println("Error");
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
The responder:
while(true) {
Socket server;
try {
server = s.accept();
DataInputStream in = new DataInputStream(server.getInputStream());
String msg = in.readUTF();
String[] broken_msg = msg.split(":");
if(broken_msg.length > 0)
System.out.println("Looping");
String ret;
if (broken[0].equalsIgnoreCase("Start")) {
ret = "Return Message";
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF(ret);
}
else if (broken[0].equalsIgnoreCase("Main")) {
//Do Useful work
}
} catch (IOException e) {
e.printStackTrace();
}
}
My output looks like this:
Looping
and:
Sent data
Received data
Sent data again
You are looping around the accept() call, accepting new connections, but your actual I/O code only reads one message per connection. You need an inner loop around the readUTF() calls, handling the entire connection until EOFException is thrown. Normally all the I/O for a connection is handled in a separate thread.
In order for programs to do repetitive actions, you would generally use looping of some sort, including for loops, while loops and do-while loops. For something like this where you don't know how many times you'd need to communicate in advance, then you would need to use a while loop, not a for loop.
Having said that, you have no while loops whatsoever inside of your connection code... so without code that would allow continued communication, your program will stop, exactly as you've programmed it to do.
Solution: fix this. Put in while loops where continued communication is needed.
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'm making a simple chat server and just made it so each connection runs on a new thread.
The old version started a single thread for the server, it did a while loop, which would stop when a stop message was sent then close the socket.
The new version loops forever and create a new thread for each new connection. Now I cannot close the socket connection.
If you press a key and the main thread stops, the socket stays open. Thus when I run the program again I need to change the socket number.
code of server
while(true)
{
///////////////////////////////////////////////////
// get a new connection
///////////////////////////////////////////////////
System.out.println("Aceepting connections on port 1030 \r");
try{
// Get New Connection
// wait for ever on accepting new connections
server.setSoTimeout(0);
connection=server.accept();
cConnection thread = new cConnection("thread3", connection);
} catch(IOException ec)
{
System.out.println(ec.getMessage());
}
}
code that starts server
Now each message comes in on a new thread, so I cannot tell it to stop and close the socket.
You need to provide a flag that must be globally accesible, so when some client wants to stop the server then change the variable ans stops the bucle. By example:
class YourServer {
private static boolean execute = true;
public static synchronized void stop() {
execute = false;
}
public void yourMethod() {
while(execute) {
// implement your server here
}
}
}
When a client send the command STOP you must be do
YourServer.stop();
If you want a stop command to stop the server you can call System.exit() to force the program to store or just closing server is likely to be all you need.
Looking into your problem, I understood one thing, that since you are putting
while (true), so your control always gets stuck at connection=server.accept(); listening for a new connection. So in order to stop the sockets you need to first find a way to stop looping in that while loop. Either you can set a Variable, like (int clientsConnected) to check the number of Clients, when that comes to zero stop that while loop. So you can stop your sockets.
Below is my sample code for clients which is doing the same thing for closing the Sockets.
Hopefully this solves your problem.
class GetNamesFromServer implements Runnable
{
private Socket sForName, sForId;
private BufferedReader in, inForName, inForId;
private PrintWriter outForName, outForId;
private static String clientNames;
public GetNamesFromServer(Socket s1, Socket s2)
{
sForName = s1;
sForId = s2;
}
public void run()
{
try
{
outForName = new PrintWriter(sForName.getOutputStream(), true);
outForName.println(Client.clientName);
System.out.println("Send Name : " + Client.clientName);
outForName.flush();
}
catch(IOException e)
{
System.err.println("Error sending Name to the Server.");
}
try
{
inForId = new BufferedReader(new InputStreamReader(sForId.getInputStream()));
Client.clientId = (inForId.readLine()).trim();
System.out.println("Client ID is : " + Client.clientId);
}
catch(IOException e)
{
System.err.println("Error Receiving ID from Server.");
}
try
{
inForName = new BufferedReader(new InputStreamReader(sForName.getInputStream()));
while (true)
{
clientNames = inForName.readLine();
if (clientNames != null && clientNames != "")
{
clientNames = clientNames.substring(1, clientNames.length() - 1);
System.out.println("Names Received : " + clientNames);
String[] names = clientNames.split(", ");
Client.nameClients.clear();
for (String element: names)
Client.nameClients.add(element);
Client.nPane.setText("");
int size = Client.nameClients.size();
System.out.println("Size of list : " + size);
for (int i = 0; i < size; i++)
{
String name = Client.nameClients.get(i);
String colour = Character.toString(name.charAt(0));
name = name.substring(1, name.length()) + "\n";
appendToNamePane(name, ReceiveMessages.getColour(Integer.parseInt(colour)), "Lucida Console");
}
System.out.println("Clients Online : " + Client.nameClients);
}
int index = Client.nameClients.indexOf(Client.clientId + Client.clientName);
**if (index == -1)
{
sForName.close();
break;
}**
}
}
catch(IOException e)
{
System.err.println("Error Receiving Names of Clients from Server");
}
}
NEW EDITION :
You can add a cap to maximum number of clients that can connect, once that reaches your while loop will not go to connection = server.accept(); and hence when they are done chatting (after some time) i.e. totalClients = 0, you can stop your sockets as well, to stop the program.
if (totalClients == 0)
{
socket.close();
serverSocket.close();
}
Regards