I've been playing around with sockets recently, but I've come across a problem...
I'm getting a "java.net.SocketException: socket closed" exception when I receive data from the server. I haven't closed the socket anywhere, in fact, the only place I use close() is on the scanner to read text from System.in;
Here is my code:
Client:
package packets.sidedcomputer;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import packets.MessagePacket;
import packets.sender.PacketSender;
import packets.side.Side;
public class Client extends SidedComputer
{
volatile boolean finished = false;
volatile String username;
volatile Server server;
public Socket clientSocket;
public ClientReciever reciever;
public Client(Server server, String username) throws UnknownHostException, IOException
{
this.username = username;
this.server = server;
this.reciever = new ClientReciever(this);
}
public void stopClient()
{
finished = true;
}
#Override
public void run()
{
Scanner scanner = new Scanner(System.in);
reciever.start();
while(!finished)
{
try
{
this.clientSocket = new Socket("192.168.1.25", 10501);
String line;
while((line = scanner.nextLine()) != null)
{
PacketSender sender = new PacketSender();
System.out.println("Client sending message \"" + line + "\" to server");
sender.sendPacket(new MessagePacket(line, username), clientSocket);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
scanner.close();
}
#Override
public Side getSide()
{
return Side.CLIENT;
}
}
Server:
package packets.sidedcomputer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import packets.Packet;
import packets.data.PacketData;
import packets.info.ClientInfo;
import packets.reciever.PacketReciever;
import packets.sender.PacketSender;
import packets.side.Side;
public class Server extends SidedComputer
{
volatile boolean finished = false;
public ServerSocket serverSocket;
public volatile List<ClientInfo> clients = new ArrayList<ClientInfo>();
public void stopServer()
{
finished = true;
}
public Server()
{
try
{
serverSocket = new ServerSocket(10501);
}
catch (IOException e)
{
e.printStackTrace();
}
}
#Override
public void run()
{
try
{
while (!finished)
{
Socket clientSocket = serverSocket.accept();
if(clientSocket != null)
{
ClientInfo clientInfo = new ClientInfo(clientSocket);
this.clients.add(clientInfo);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String dataString;
while((dataString = in.readLine()) != null)
{
PacketReciever packetReciever = new PacketReciever();
PacketData packetData = new PacketData();
packetData.decodeInto(dataString);
Packet packet = packetReciever.recievePacket(packetData, packetData.packetID, getSide(), clientSocket.getLocalAddress().getHostAddress().toString(), clientSocket.getLocalPort() + "");
PacketSender packetSender = new PacketSender();
for (ClientInfo client : this.clients)
{
PrintWriter out = new PrintWriter(client.socket.getOutputStream(), true);
packetSender.sendPacketToClient(packet, out);
}
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
}
#Override
public Side getSide()
{
return Side.SERVER;
}
}
Packet Sender:
package packets.sender;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import packets.Packet;
import packets.data.PacketData;
public class PacketSender implements IPacketSender
{
#Override
public void sendPacket(Packet packet, Socket socket)
{
if(packet.getDefualtID() == 0)
{
PacketData packetData = new PacketData(packet.getDefualtID());
packet.writeData(packetData);
String data = packetData.encodeIntoString();
sendData(socket, data);
}
}
protected void sendData(Socket socket, String data)
{
try
{
try
(
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
)
{
out.println(data);
}
catch (IOException e)
{
System.err.println("Couldn't get I/O for the connection to " + socket);
System.exit(1);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void sendPacketToClient(Packet packet, PrintWriter out)
{
PacketData packetData = new PacketData(packet.getDefualtID());
packet.writeData(packetData);
String data = packetData.encodeIntoString();
out.println(data);
}
}
Client Receiver:
package packets.sidedcomputer;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import packets.data.PacketData;
import packets.reciever.PacketReciever;
import packets.side.Side;
public class ClientReciever extends Thread
{
public Client client;
public ClientReciever(Client client)
{
this.client = client;
}
volatile boolean running = true;
public void stopRunning()
{
running = false;
}
#Override
public void run()
{
while(running)
{
if(client.clientSocket != null)
{
try
{
BufferedReader in = new BufferedReader(new InputStreamReader(client.clientSocket.getInputStream()));
String line;
while((line = in.readLine()) != null)
{
PacketReciever reciever = new PacketReciever();
PacketData packetData = new PacketData();
packetData.decodeInto(line);
reciever.recievePacket(packetData, packetData.packetID, Side.CLIENT, client.clientSocket.getLocalAddress().getHostAddress().toString(), client.clientSocket.getPort() + "");
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
Packet Receiver:
package packets.reciever;
import packets.Packet;
import packets.MessagePacket;
import packets.data.PacketData;
import packets.side.Side;
public class PacketReciever implements IPacketReciever
{
#Override
public Packet recievePacket(PacketData packetData, int id, Side side, String hostName, String port)
{
Packet packet = null;
if(id == 0)
{
packet = new MessagePacket();
packet.readData(packetData);
packet.execute(side, hostName + ":" + port);
}
return packet;
}
}
I think the problem is your try-with-resources call in the sender, which will call close() at the end of the try block and hence close the Socket. Try using a single PrintWriter across all calls to sendData().
Related
Now I do realize there are lots of the same question but even after reading the answers I seem not to undertsand. So here is the code and I'll explain the problem.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server implements Runnable {
String firstName;
String lastName;
String password;
private ArrayList<ConnectionHandler> connections;
private ServerSocket server;
private boolean done;
private ExecutorService pool;
public Server() {
connections = new ArrayList<>();
done = false;
}
#Override
public void run() {
try {
server = new ServerSocket(9999);
pool = Executors.newCachedThreadPool();
while (!done) {
Socket client = server.accept();
ConnectionHandler handler = new ConnectionHandler((client));
connections.add(handler);
pool.execute(handler);
}
} catch (Exception e) {
shutdown();
}
}
public void shutdown() {
try {
done = true;
pool.shutdown();
if (!server.isClosed()) {
server.close();
}
for (ConnectionHandler ch : connections) {
ch.shutdown();
}
} catch (IOException e) {
// ignore
}
}
class ConnectionHandler implements Runnable {
private Socket client;
private BufferedReader in;
private PrintWriter out;
public void broadcast(String message) {
for (ConnectionHandler ch : connections) {
if (ch != null) {
ch.sendMessage(message);
}
}
}
public ConnectionHandler(Socket client) {
this.client = client;
}
#Override
public void run() {
try {
out = new PrintWriter((client.getOutputStream()), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out.println("To register type 1,to sign in type 2");
//TODO:for loop so only answer is 1 or 2
String message = in.readLine();
switch (message) {
case "1":
out.println("In order to register please enter your first and last name then set a password.");
out.println("Enter first name:");
firstName = in.readLine();
out.println("Enter last name:");
lastName = in.readLine();
out.println("Finally please set a password.");
password = in.readLine();
//TODO: add parameters for passcode
out.println("Now please type 2 to login");
message = in.readLine();
if (message.equals("2")) {
//TODO: copy paste from line 104-x
}
case "2":
out.println("Please enter your first name:");
String messageLogInFN= in.readLine();
out.println("Please enter your last name:");
String messageLogInLN = in.readLine();
out.println("Enter your password:");
String messageLogInPass = in.readLine();
boolean adminAccount = (messageLogInFN.equals("admin") && messageLogInLN.equals("admin") && messageLogInPass.equals("admin123cat"));
if (adminAccount) {
//TODO: add admin permissions
}
boolean Authentication = ((messageLogInFN.equals(firstName) && messageLogInLN.equals(lastName) && messageLogInPass.equals(password)));
if (Authentication) {
out.println("Welcome " + firstName + " " + lastName + "!");
System.out.println(firstName + " " + lastName + " has logged in." );
} else
out.println("Your name or password incorrect!");
}
} catch (IOException e) {
shutdown();
}
}
public void sendMessage(String message) {
out.println(message);
}
public void shutdown() {
try {
in.close();
out.close();
if (!client.isClosed()) {
client.close();
}
} catch (IOException e) {
//ignore
}
}
}
public static void main(String[] args) {
Server server = new Server();
server.run();
}
So I am learning java and saw a tutorial on youtube for a chat room, I programed it following the tutorial, and then I wanted to have a chat room with accounts so I got to coding. Now here is the thing even though I am able to have several devices connected to the server when 2 accounts register the server forgets the first one so there can only be 1 account at the same time. What I am trying to do is have an account system where everyone has their own account that they log in with their first name, last name and passwords. But it doesnt seem to work. How can I make it so that the server doesn't forget all accounts except for the last one that registered?
Edit: Here is the client code if it helps.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Client implements Runnable {
private boolean done;
private Socket client;
private BufferedReader in;
private PrintWriter out;
#Override
public void run() {
try {
client = new Socket("127.0.0.1", 9999);
out = new PrintWriter((client.getOutputStream()), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
InputHandler inHandler = new InputHandler();
Thread t = new Thread(inHandler);
t.start();
String inMessage;
while ((inMessage = in.readLine()) != null) {
System.out.println(inMessage);
}
} catch (IOException e) {
shutdown();
}
}
public void shutdown() {
done = true;
try {
in.close();
out.close();
if(!client.isClosed()) {
client.close();
}
} catch (IOException e) {
//ignore
}
}
class InputHandler implements Runnable {
#Override
public void run() {
try {
BufferedReader inReader = new BufferedReader(new InputStreamReader(System.in));
while (!done) {
String message = inReader.readLine();
if(message.equals("/quit")) {
out.println(message);
inReader.close();
shutdown();
} else {
out.println(message);
}
}
} catch (IOException e) {
shutdown();
}
}
}
public static void main(String[] args) {
Client client = new Client();
client.run();
}
}
Also as I said most of this isnt my code and I followed a yt tutorial.
I am trying to write a multi-threaded server program with 2 servers.I am testing with 2 clients.Sometimes depending on a md5 hashcode a client connected to a server has to disconnect from said server and connect to the other one.Sometimes this happens without any problems and sometimes I get java.net.SocketException: Socket closed.Here s the code
Broker class(Server):
import java.io.IOException;
import java.math.BigInteger;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.*;
import java.util.ArrayList;
import java.util.List;
public class Broker extends Node implements Runnable {
private static List<Publisher> registeredpublishers = new ArrayList<Publisher>();
private static List<Consumer> registeredConsumers = new ArrayList<Consumer>();
public static List<Consumer> GetConsumers(){
return registeredConsumers;
}
public String Name;
public Integer port;
public Broker(Integer port,String name){
this.port=port;
this.Name=name;
}
ServerSocket providerSocket;
Socket connection = null;
String ip="127.0.0.1";
BigInteger myKeys;
public void run(){
calculateKeys();
Node.getBrokers().add(this);
openServer();
}
void calculateKeys(){
String g =ip+ (port != null ? port.toString() : null);
MessageDigest m = null;
try {
m = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
m.reset();
m.update(g.getBytes());
byte[] digest = m.digest();
myKeys = new BigInteger(1,digest);
BigInteger a=new BigInteger("25");
myKeys=myKeys.mod(a);
System.out.println(myKeys);
}
void openServer()throws NullPointerException {
try {
providerSocket = new ServerSocket(this.port, 10);
while (true) {
acceptConnection();
new BrokerHandler(connection,this).start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
providerSocket.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
void acceptConnection()throws NullPointerException {
try {
connection = providerSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("client connected.");
{
}
}
public static void main(String args[]) {
new Thread(new Broker(54319,"First")).start();
new Thread(new Broker(12320,"Second")).start();
}
}
BrokerHandler Class
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.math.BigInteger;
import java.net.Socket;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class BrokerHandler extends Thread implements Serializable {
ObjectInputStream in;
ObjectOutputStream out;
String f;
BigInteger theirKeys;
Broker broker;
Object e;
Message request;
public BrokerHandler(Socket connection,Broker broker) throws NullPointerException{
try {
in = new ObjectInputStream(connection.getInputStream());
out =new ObjectOutputStream(connection.getOutputStream());
try {
this.request=(Message)in.readObject();
this.f=request.artist;
this.e =request.entity;
this.broker=broker;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
if(this.e instanceof Consumer){
calculateMessageKeys(this.request);
checkBroker(this.broker,(Consumer) e);
}
}
public synchronized void disconnect(Socket connection){
try {
in.close();
out.close();
} catch (IOException ex) {
ex.printStackTrace();
}finally {
try {
connection.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public void checkBroker(Broker broker,Consumer consumer) {
int intMyKeys = broker.myKeys.intValue();
int intTheirKeys = theirKeys.intValue();
if (intTheirKeys > 23) {
intTheirKeys = intTheirKeys % 23;
}
if (intTheirKeys <= intMyKeys && intTheirKeys >= intMyKeys - 11) {
consumer.Register(broker, f);
System.out.println(broker.Name + "Client Connected and Registered");
} else {
int thePort = 0;
System.out.println(broker.Name + "Client changing server");
for (Broker broker1 : Node.getBrokers()) {
int KEYS = broker1.myKeys.intValue();
if (intTheirKeys <= KEYS && intTheirKeys >= KEYS - 11) {
thePort = broker1.port;
System.out.println(thePort);
}
}
disconnect(broker.connection);
Consumer a = new Consumer(consumer.artist, thePort);
new ConsumerHandler(a).start();
}
}
public void calculateMessageKeys(Message request) {
MessageDigest m = null;
try {
m = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
m.reset();
m.update(f.getBytes());
byte[] digest = m.digest();
theirKeys = new BigInteger(1,digest);
BigInteger mod=new BigInteger("25");
theirKeys=theirKeys.mod(mod);
System.out.println(theirKeys);
}
}
Consumer class
import java.io.*;
import java.util.Random;
public class Consumer extends Node implements Serializable {
String artist;
Random r=new Random();
int max=12320;
int min=54319;
int port;
Message request;
public Consumer(String artist){
this.artist=artist;
this.port=new Random().nextBoolean() ? max : min;
request= new Message(artist,this.getConsumer());
}
public Consumer(String artist,int port){
this.artist=artist;
this.port=port;
request= new Message(artist,this.getConsumer());
}
public Consumer getConsumer(){
return this;
}
public void Register(Broker broker,String ArtistName){
broker.GetConsumers().add(this);
System.out.println(this.artist);
}
}
ConsumerHandle Class
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class ConsumerHandler extends Thread{
Consumer consumer;
public ConsumerHandler(Consumer consumer){
this.consumer=consumer;
}
void connect(int port) {
Socket requestSocket=null;
ObjectOutputStream out = null;
ObjectInputStream in = null;
try {
requestSocket = new Socket("127.0.0.1", consumer.port);
out = new ObjectOutputStream(requestSocket.getOutputStream());
in = new ObjectInputStream(requestSocket.getInputStream());
System.out.println("Message created.");
out.writeObject(consumer.request);
} catch (UnknownHostException unknownHost) {
System.err.println("You are trying to connect to an unknown host!");
} catch (IOException ioException) {
ioException.printStackTrace();
} finally {
try {
in.close();
out.close();
requestSocket.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
public void run(){
connect(consumer.port);
}
public static void main(String args[]) {
Consumer a=new Consumer("Kevin MacLeod");
Consumer b=new Consumer("Alexander Narakada");
new ConsumerHandler(a).start();
new ConsumerHandler(b).start();
}
}
and the stack trace of when it happens:
java.net.SocketException: Socket closed
at java.base/sun.nio.ch.NioSocketImpl.ensureOpenAndConnected(NioSocketImpl.java:166)
at java.base/sun.nio.ch.NioSocketImpl.beginRead(NioSocketImpl.java:232)
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:300)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:351)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:802)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:937)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:932)
at java.base/java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2778)
at java.base/java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:3105)
at java.base/java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:3115)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1597)
at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2410)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2304)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2142)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1646)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:464)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
at BrokerHandler.<init>(BrokerHandler.java:26)
at Broker.openServer(Broker.java:59)
at Broker.run(Broker.java:34)
at java.base/java.lang.Thread.run(Thread.java:830)
I'm trying to implement a SCTP connection, everything works fine from the server's side but when I run the client program I get the following error:
java.net.ConnectException: Connection refused
at sun.nio.ch.SctpNet.connect0(Native Method)
at sun.nio.ch.SctpNet.connect(SctpNet.java:73)
at sun.nio.ch.SctpChannelImpl.connect(SctpChannelImpl.java:372)
at sun.nio.ch.SctpChannelImpl.connect(SctpChannelImpl.java:438)
at com.sun.nio.sctp.SctpChannel.open(SctpChannel.java:221)
at com.eska.sctp.client.SCTPClient.<init>(SCTPClient.java:20)
at com.eska.sctp.client.SCTPClient.main(SCTPClient.java:62)
The Server Code:
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;
import com.sun.nio.sctp.AbstractNotificationHandler;
import com.sun.nio.sctp.AssociationChangeNotification;
import com.sun.nio.sctp.AssociationChangeNotification.AssocChangeEvent;
import com.sun.nio.sctp.HandlerResult;
import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpServerChannel;
import com.sun.nio.sctp.ShutdownNotification;
public class SCTPServer {
private final static int SERVER_PORT = 1111;
private final static int BUFFER_SIZE = 1024;
private SctpServerChannel ssc;
public SCTPServer(int port) throws IOException {
this.ssc = SctpServerChannel.open();
// m.alkhader
// this.ssc.bind(new InetSocketAddress(port));
this.ssc.bind(new InetSocketAddress("127.0.0.1", port));
System.out.println("SCTP server started.");
System.out.println("Local addresses :");
Iterator iterator = this.ssc.getAllLocalAddresses().iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
public void launch() throws IOException {
ByteBuffer buf = ByteBuffer.allocate(BUFFER_SIZE);
CharBuffer cbuf = CharBuffer.allocate(BUFFER_SIZE);
Charset charset = Charset.forName("ISO-8859-1");
CharsetDecoder decoder = charset.newDecoder();
while (true) {
System.out.println("Waiting for client connection...");
SctpChannel sc = this.ssc.accept();
System.out.println("Client connected");
System.out.println("Remote adresses :");
Iterator iterator = sc.getRemoteAddresses().iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
AssociationHandler assocHandler = new AssociationHandler();
MessageInfo messageInfo = null;
do {
buf.clear();
cbuf.clear();
messageInfo = sc.receive(buf, null, assocHandler);
buf.flip();
messageInfo.unordered(true);
if (messageInfo != null && buf.limit() > 0) {
decoder.decode(buf, cbuf, true);
cbuf.flip();
System.out.print("Stream(" + messageInfo.streamNumber()
+ "):");
System.out.println(cbuf);
}
} while (messageInfo != null && buf.limit() > 0);
System.out.println("Connection closed by peer.");
}
}
public static void main(String[] args) {
try {
SCTPServer server = new SCTPServer(SERVER_PORT);
server.launch();
} catch (IOException e) {
System.out.println("Error : " + e.getMessage());
}
}
static class AssociationHandler extends AbstractNotificationHandler {
public HandlerResult handleNotification(
AssociationChangeNotification not, PrintStream stream) {
if (not.event().equals(AssocChangeEvent.COMM_UP)) {
int outbound = not.association().maxOutboundStreams();
int inbound = not.association().maxInboundStreams();
stream.printf("New association setup with %d outbound streams"
+ ", and %d inbound streams.\n", outbound, inbound);
}
return HandlerResult.CONTINUE;
}
public HandlerResult handleNotification(ShutdownNotification not,
PrintStream stream) {
stream.printf("The association has been shutdown.\n");
return HandlerResult.RETURN;
}
}
}
The Client Code:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.Scanner;
import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.SctpChannel;
public class SCTPClient {
private SctpChannel sc;
private final static int SERVER_PORT = 1111;
private final static int BUFFER_SIZE = 1024;
public SCTPClient(String addr, int port) throws IOException {
this.sc = SctpChannel.open(new InetSocketAddress(addr, port), 0, 0);
}
public void start() throws IOException {
MessageInfo messageInfo = MessageInfo.createOutgoing(null, 0);
Charset charset = Charset.forName("ISO-8859-1");
CharsetEncoder encoder = charset.newEncoder();
ByteBuffer buf = ByteBuffer.allocate(BUFFER_SIZE);
CharBuffer cbuf = CharBuffer.allocate(BUFFER_SIZE);
Scanner scan = new Scanner(System.in);
int i = 0;
int max = this.sc.association().maxInboundStreams();
// messageInfo.unordered(true);
while (scan.hasNext()) {
buf.clear();
cbuf.clear();
cbuf.put(scan.nextLine());
cbuf.flip();
encoder.encode(cbuf, buf, true);
buf.flip();
messageInfo.streamNumber(i % max);
this.sc.send(buf, messageInfo);
i++;
}
}
public void stop() throws IOException {
this.sc.close();
}
public static void main(String[] args) {
try {
System.out.println("Client");
SCTPClient client = new SCTPClient("127.0.0.1", SERVER_PORT);
// SCTPClient client = new SCTPClient("192.168.0.1", SERVER_PORT);
System.out.println("Hello Client");
client.start();
client.stop();
} catch (IOException e) {
System.out.println("Error : " + e.getMessage());
e.printStackTrace();
}
}
}
everything works fine from the server's side
This is my first time messing around with Sockets, and it was working up until now. Basically, I have a custom ServerSocket class named Server and a custom Socket class named Client.
When Client tries to connect to Server, Server performs a little check to make sure it is actually Client that it trying to make the connection, and not some other socket, because Client has certain methods that I need.
However, this check always returns false. Here is my Server connection code:
package me.eli.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import me.eli.client.Client;
public class Server extends ServerSocket {
private final Map<Client, IOPair> clients = new HashMap<Client, IOPair>();
public Server(final int port) throws IOException {
super(port);
System.out.println("Server started on " + getLocalPort() + "... Waiting for client!");
}
public Client waitOnClient() throws IOException {
final Socket generalClient = accept();
final Client client;
if(!(generalClient instanceof Client)) {
client = null;
PrintWriter out = new PrintWriter(generalClient.getOutputStream(), true);
out.println("Access denied: " + generalClient.getClass().getSimpleName());
log("Invalid client: " + generalClient.getClass().getName() + " (" + generalClient.getInetAddress().getHostAddress() + ")");
out.close();
} else
client = (Client) generalClient;
if(client == null)
return null;
client.setServer(this);
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
broadcast(client.getName() + " has joined.");
clients.put(client, new IOPair(in, out));
System.out.println("Client (" + client.getName() + ") connected from " + client.getInetAddress().getHostAddress());
out.println("Connected! Welcome to the server.");
return client;
}
#Override
public void close() throws IOException {
for(Client c : getClients())
kick(c, "Server closed");
super.close();
}
public void kick(Client c, String reason) {
try {
c.message("disconnect", reason);
c.close();
} catch(IOException e) {
log("Failed to kick " + c.getName() + ": " + e.getMessage());
c.message("error", "Failed to disconnect");
}
}
public void log(String message) {
getServerOut().println(message);
}
public void log(String source, String message) {
log("<" + source + "> " + message);
}
public void broadcast(String message) {
log("broadcast", message);
for(Client c : getClients())
c.message("broadcast", message);
}
public Client[] getClients() {
return clients.keySet().toArray(new Client[clients.keySet().size()]);
}
public BufferedReader getClientIn(Client c) {
return clients.get(c).getIn();
}
public PrintWriter getClientOut(Client c) {
return clients.get(c).getOut();
}
public InputStream getServerIn() {
return System.in;
}
public PrintStream getServerOut() {
return System.out;
}
public static boolean isServerRunningOn(final int port) {
try {
new ServerSocket(port).close();
return false;
} catch(IOException e) {
return true;
}
}
}
And here is my Client connection code:
package me.eli.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
import me.eli.server.IOPair;
import me.eli.server.Server;
public class Client extends Socket {
private Server server;
private final IOPair serverio;
private final String name;
public Client(final String host, final int port) throws IOException {
this(host, port, "Guest-" + (int) (Math.random() * 10000));
}
public Client(final String host, final int port, final String name) throws IOException {
super(host, port);
System.out.println("Connected to server on " + host + ":" + port);
BufferedReader in = new BufferedReader(new InputStreamReader(getInputStream()));
PrintWriter out = new PrintWriter(getOutputStream(), true);
this.name = name;
this.serverio = new IOPair(in, out);
String input;
if((input = in.readLine()) != null)
System.out.println("<Welcome message> " + input);
out.println("Yay! I'm connected!");
}
#Override
public synchronized void close() throws IOException {
if(serverio != null) {
if(server != null)
server.broadcast(getName() + " has disconnected.");
message("server", "Disconnected.");
super.close();
serverio.getIn().close();
serverio.getOut().close();
} else
super.close();
}
public void message(String source, String message) {
getClientOut().println("<" + source + "> " + message);
}
public String getName() {
return name;
}
public void setServer(Server server) {
this.server = server;
}
public Server getServer() {
return server;
}
public BufferedReader getServerIn() {
return serverio.getIn();
}
public PrintWriter getServerOut() {
return serverio.getOut();
}
public InputStream getClientIn() {
return System.in;
}
public PrintStream getClientOut() {
return System.out;
}
}
I'm not the most experienced with networking, but this confuses me because I do indeed connect with my Client class. Thanks in advance!
Server performs a little check to make sure it is actually Client that it trying to make the connection
Impossible and nonsensical. The Client class is at the other end of the connection. It is not magically transmitted to your accept() method. If you want to validate your client you will have to build something into your application protocol.
Notes:
Calling Client.setServer() is similarly futile. It is not magically transmitted to the client.
It is possible to get your ServerSocket-derived class to create Client objects instead of Socket objects in its accept() method, but that doesn't actually solve the issue you're trying to solve.
I am trying to implement a persistent http server in java, being new in socket programming, I am unaware of the complications.
But run function of ThreadHandler class, it stucks forever and keep waiting, but at the same time if new request comes a new connection is being made instead of using the previous connection itself (while the initial connection keep waiting for request).
Please suggest the correction
here is my server code that calls ThreadHandler for threading.
Server code
package httpServer;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
public class Server {
static int countofconnections = 0;
public static void main(String[] args) throws IOException {
int port = 14998;
ServerSocket socketServerSocket = new ServerSocket(port);
while(true) {
Socket socketClientSocket = socketServerSocket.accept();
countofconnections++;
//Runnable handler = new TinyHttpdSocketHandler(socket);
ThreadHandler threadHandler = new ThreadHandler(socketClientSocket);
Thread socketThread = new Thread(threadHandler, "Thread for " + socketClientSocket.toString());
System.out.println(" connection count is now : " + countofconnections+ " ");
socketThread.setDaemon(true);
socketThread.start();
}
}
}
ThreadHandler code:
package httpServer;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.SocketTimeoutException;
//import java.util.ArrayList;
public class ThreadHandler implements Runnable{
Socket socketClientSocket;
//ServerSocket socketServerSocket;
ThreadHandler(Socket socketClientSocket){
this.socketClientSocket = socketClientSocket;
//this.socketServerSocket = socketServerSocket;
}
#Override
public void run(){
boolean alive = false;
try {
int count = 0;
socketClientSocket.setSoTimeout(40000);
BufferedReader inputFromClient = new BufferedReader(new InputStreamReader(socketClientSocket.getInputStream()));
DataOutputStream outputToClient = new DataOutputStream(socketClientSocket.getOutputStream());
String messegeFromClient = inputFromClient.readLine();
System.out.println(messegeFromClient);
while(messegeFromClient!=null) {
String requestString = messegeFromClient;
System.out.println("entering while loop");
//String in = inputFromClient.readLine();
while(messegeFromClient!=null && !messegeFromClient.equals("")) {
//System.out.printlnln(in);
messegeFromClient = inputFromClient.readLine();
//System.out.println(messegeFromClient);
if(messegeFromClient.startsWith("Connection:")) {
String[] connectionTimeString = messegeFromClient.split(" ");
if(connectionTimeString[1].equals("keep-alive")) {
alive = true;
//System.out.println("keep alive found");
}
}
}
count++;
System.out.println(count);
//System.out.printlnln( messegeFromClient);
String[] tokensStrings = requestString.split(" ");
if(tokensStrings[0].equals("GET")) {
String requestedFilename = tokensStrings[1];
if(requestedFilename.startsWith("/")) {
requestedFilename = requestedFilename.substring(1);
if(requestedFilename.startsWith("~")) {
requestedFilename = "/home/suman/users/"+requestedFilename.substring(1);
}
else {
requestedFilename = "/home/suman/public_html/"+requestedFilename;
}
System.out.println(requestedFilename);
}
File filetosend = new File(requestedFilename);
int filesize = (int) filetosend.length();
FileInputStream fileStream = null;
boolean fileFound = true;
try {
fileStream = new FileInputStream(requestedFilename);
} catch (Exception e) {
fileFound = false;
}
if(fileFound) {
byte[] fileinByte =new byte[filesize];
fileStream.read(fileinByte);
outputToClient.writeBytes("HTTP/1.0 200 Document Follows\r\n");
outputToClient.writeBytes("Content-Length: "+filesize+"\r\n\r\n");
outputToClient.write(fileinByte, 0, filesize);
}
else {
outputToClient.writeBytes("HTTP/1.0 404 Document NOT FOUND\r\n\r\n");
outputToClient.writeBytes("404 document not found");
}
outputToClient.flush();
if(alive) {
socketClientSocket.setKeepAlive(true);
socketClientSocket.setSoTimeout(100000);
}
else {
socketClientSocket.close();
System.out.println("closing socket");
break;
}
//socketClientSocket.setSoTimeout(5000);
}
System.out.println("waiting");
messegeFromClient=inputFromClient.readLine();
while( messegeFromClient == null ) {
//this code should be skipped when a new request is made since message from from client will no longer be null in that case
messegeFromClient=inputFromClient.readLine();
}
if(messegeFromClient==null) {
System.out.println("messege is null... I don't think it would be ever executed.");
}
}
socketClientSocket.close();
System.out.println("closing socket 2");
} catch ( SocketTimeoutException e) {
try {
socketClientSocket.close();
System.out.println("socket closed");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} catch (IOException ie) {
ie.printStackTrace();
}
}
}