Hello, I have a questions in TCP client to server communication:
This is what is require me to do:
First of all, if we run the program from multible command line or multible PC it will run the same program. ( of cource )
Second, the program should read from the .txt file and assigned each node to what node conected. ( done that )
Thired, the program should have the server and the client in the same class we could call it a Node.java for example.
Fourth, when the Node.java want to send a message to other Node it pretend to be a client but the other Node switch to server to resive the message and replay to the message and visa Versa.
Fifth, we should assigned each server to a port number witch is in the .txt file
Sixth, the client should recognize when he resived the message, the message if from the server. And the server should recgonize the IP address and the port number it comes from a client.
Am confused about how i combined the server and client class to gether! And i have a meesage class that does the communication but it seems that it send to the same client! Am confused about how i asigned the prot number to the server for example node one should run in PC 1 and have the port number 2020 and Node 2 is conected to PC2 but have the pord number 5050! Of course each of nodes have a client and server running.
Here is my code:
Here is my main class:
public abstract class CSCI438 extends Thread {
public static void main(String[] args) {
TCPClient tc = new TCPClient();
TCPServer ts = new TCPServer();
ts.run();
tc.run();
}
}
here is my Message class
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.logging.Logger;
public abstract class Message {
private final static Logger LOGGER = Logger.getLogger("MESSAGE");
public abstract void fromBytes(ByteBuffer buffer);
public abstract void toBytes(ByteBuffer buffer);
private String messageType() {
return getClass().getSimpleName();
}
public static void stringToMessage(ByteBuffer buffer, String str) {
byte[] bytes = str.getBytes();
int len = bytes.length;
buffer.putShort((short) len);
buffer.put(bytes);
}
public static String stringFromMessage(ByteBuffer buffer) {
int len = buffer.getShort();
byte[] bytes = new byte[len];
buffer.get(bytes);
return new String(bytes);
}
public static Message nextMessageFromSocket(SocketChannel socket, ByteBuffer dataBuffer) throws IOException {
//read the first 4 bytes to get the message length
ensureBytesAvailable(socket, dataBuffer, 4);
int length = dataBuffer.getInt();
// read the rest of the messsage (as denoted by length)
ensureBytesAvailable(socket, dataBuffer, length);
String type = stringFromMessage(dataBuffer);
Message message = null;
if(type.equals(TimeRequestMsg.class.getSimpleName())) {
message = new TimeRequestMsg();
} else if(type.equals(TimeResponnseMsg.class.getSimpleName())) {
message = new TimeResponnseMsg();
}
if(message == null)
throw new IOException("Unknown message type: " + type);
message.fromBytes(dataBuffer);
LOGGER.info("Message read from socket: " + message);
return message;
}
public static void sendMessage(SocketChannel channel, Message toSend) throws IOException{
ByteBuffer bbMsg = ByteBuffer.allocate(2048);
stringToMessage(bbMsg, toSend.messageType());
toSend.toBytes(bbMsg);
bbMsg.flip();
ByteBuffer bbOverall = ByteBuffer.allocate(10);
bbOverall.putInt(bbMsg.remaining());
bbOverall.flip();
long written = channel.write(new ByteBuffer[] {bbOverall, bbMsg});
LOGGER.info("Message written to socket: " + toSend + ", length was: " + written);
}
@SuppressWarnings("unused")
private static void ensureBytesAvailable(SocketChannel socket, ByteBuffer buffer, int required) throws IOException {
if(buffer.position() != 0) {
buffer.compact();
}
while(buffer.position() < required) {
int len = socket.read(buffer);
if(!socket.isOpen() || len <= 0)
throw new IOException("Socket is closed while reading");
LOGGER.info("Bytes now in buffer: " + buffer.remaining() + " read from socket: " + len);
}
buffer.flip();
}
}
Here is my Node class
public class Node {
private String hostName;
private int nodeID, udpPort, nodeOne, nodeTwo, mtuBytes;
public Node() {
}
public Node(int nodeID, String hostName, int udpPort, int nodeOne, int nodeTwo, int mtuBytes) {
super();
this.nodeID = nodeID;
this.hostName = hostName;
this.udpPort = udpPort;
this.nodeOne = nodeOne;
this.nodeTwo = nodeTwo;
this.mtuBytes = mtuBytes;
}
public int getNodeID() {
return nodeID;
}
public void setNodeID(int nodeID) {
this.nodeID = nodeID;
}
public String getHostName() {
return hostName;
}
public void setHostName(String hostName) {
this.hostName = hostName;
}
public int getUdpPort() {
return udpPort;
}
public void setUdpPort(int udpPort) {
this.udpPort = udpPort;
}
public int getNodeOne() {
return nodeOne;
}
public void setNodeOne(int nodeOne) {
this.nodeOne = nodeOne;
}
public int getNodeTwo() {
return nodeTwo;
}
public void setNodeTwo(int nodeTwo) {
this.nodeTwo = nodeTwo;
}
public int getMtuBytes() {
return mtuBytes;
}
public void setMtuBytes(int mtuBytes) {
this.mtuBytes = mtuBytes;
}
@Override
public String toString() {
return "ReadData [nodeID=" + nodeID + ", hostName=" + hostName + ", udpPort=" + udpPort + ", nodeOne=" + nodeOne
+ ", nodeTwo=" + nodeTwo + ", mtuBytes=" + mtuBytes + "]";
}
}
here is my Client class:
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Scanner;
public class TCPClient extends Thread{
static Node n = new Node();
static ArrayList<Node> linkNode = new ArrayList<Node>();
@Override
public void run() {
// TODO Auto-generated method stub
String sentence;
String modifiedSentence;
int nodeID;
String itcNumber;
@SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
try {
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
@SuppressWarnings("unused")
BufferedReader nodeFromUser = new BufferedReader(new InputStreamReader(System.in));
BufferedReader sendToNode = new BufferedReader(new InputStreamReader(System.in));
// First value has to be an Integer
Socket clientSocket = new Socket("", 12);
System.out.print("Enter node ID: ");
nodeID = sc.nextInt();
System.out.print("Enter itc: ");
itcNumber = sc.next();
assignFromFile(itcNumber);
for (Node node : linkNode) {
if (nodeID == node.getNodeID()) {
System.out.println("welcome host " + node.getNodeID());
System.out.println("Neighbors: " + node.getNodeOne() + " & " + node.getNodeTwo());
}
}
System.out.print("Enter message: ");
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
DataOutputStream sendDestNode = new DataOutputStream(clientSocket.getOutputStream());
@SuppressWarnings("unused")
DataOutputStream sendFile = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
int destNode;
System.out.print("Enter destination node: ");
destNode = sendToNode.read();
outToServer.writeBytes(sentence + '\n');
sendDestNode.writeByte(destNode);
//sendFile.writeBytes(itcNumber + '\n');
modifiedSentence = inFromServer.readLine();
System.out.println("From Server: " + modifiedSentence);
clientSocket.close();
} catch (IOException e) {
}
}
private void assignFromFile(String itcFile) throws FileNotFoundException {
@SuppressWarnings("resource")
Scanner docScan = new Scanner(new File(itcFile + ".txt"));
String data;
while (docScan.hasNextLine()) {
data = docScan.nextLine();
String[] word = data.split(" ");
n = new Node(Integer.parseInt(word[0]), word[1], Integer.parseInt(word[2]), Integer.parseInt(word[3]),
Integer.parseInt(word[4]), Integer.parseInt(word[5]));
linkNode.add(n);
}
}
}
and here is my server class:
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Scanner;
public class TCPServer extends Thread {
static Node node;
static ArrayList<Node> linkNode;
@Override
public void run() {
String clientSentence;
String capitalizedSentence;
try {
@SuppressWarnings("resource")
ServerSocket welcomeSocket = new ServerSocket(12);
while (true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
int destNode;
@SuppressWarnings("unused")
String fileRead;
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
@SuppressWarnings("unused")
DataOutputStream messageToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
destNode = inFromClient.read();
capitalizedSentence = clientSentence.toUpperCase() + '\n';
System.out.println(capitalizedSentence);
System.out.println(Integer.valueOf(destNode));
outToClient.writeBytes(capitalizedSentence);
/* destNode = receiveDestNode.read();
fileRead = receiveFile.readLine();
System.out.println(destNode);TCPClient.java
readFromFile(fileRead);
clientSentence = inFromClient.readLine();
String word[] = clientSentence.split(" ");
System.out.println(word[0].toString());
System.out.println(word[1].toString());
capitalizedSentence = clientSentence.toUpperCase() + '\n';
for (Node n : linkNode) {
if (destNode == n.getNodeID()) {
messageToClient.writeBytes(clientSentence + '\n');
}
}
outToClient.writeBytes(capitalizedSentence + '\n');
System.out.println(capitalizedSentence);*/
}
} catch (IOException e) {
}
// TODO Auto-generated method stub
}
@SuppressWarnings("unused")
private void readFromFile(String itcFile) throws FileNotFoundException {
@SuppressWarnings("resource")
Scanner docScan = new Scanner(new File(itcFile + ".txt"));
String data;
while (docScan.hasNextLine()) {
data = docScan.nextLine();
String[] word = data.split(" ");
node = new Node(Integer.parseInt(word[0]), word[1], Integer.parseInt(word[2]), Integer.parseInt(word[3]),
Integer.parseInt(word[4]), Integer.parseInt(word[5]));
linkNode.add(node);
}
}
}
here is my timeRequest class:
import java.nio.ByteBuffer;
import java.util.TimeZone;
public class TimeRequestMsg extends Message {
private String timeZone;
public String getTimeZone(){
return timeZone;
}
public void setTimeZone(TimeZone zone){
timeZone = zone.getID();
}
@Override
public String toString(){
return "TimeRequestMsg{timeZone='" + timeZone + "'}";
}
public void fromBytes(ByteBuffer message){
timeZone = stringFromMessage(message);
}
public void toBytes(ByteBuffer buffer){
stringToMessage(buffer, timeZone);
}
}
and here is my respondMessage class:
import java.nio.ByteBuffer;
public class TimeResponnseMsg extends Message {
private String currentTime;
public TimeResponnseMsg(){
}
public TimeResponnseMsg(String currentTime){
this.currentTime = currentTime;
}
public String getCurrentTime(){
return currentTime;
}
@Override
public String toString(){
return "TimeRespons{currentTime = '" + currentTime + "'}";
}
public void fromBytes(ByteBuffer message){
currentTime = stringFromMessage(message);
}
public void toBytes(ByteBuffer buffer){
stringToMessage(buffer,currentTime);
}
}
here is the .txt file
1 u-01.sm201.iuk.edu 17870 2 3 500
2 u-02.sm201.iuk.edu 17871 1 3 500
3 u-03.sm201.iuk.edu 17872 1 2 500
4 u-04.sm201.iuk.edu 17873 1 5 500
5 u-05.sm201.iuk.edu 17874 1 4 500
6 u-06.sm201.iuk.edu 17875 2 7 500
7 u-07.sm201.iuk.edu 17876 2 6 500
8 u-08.sm201.iuk.edu 17877 3 9 500
9 u-09.sm201.iuk.edu 17878 3 8 500
1 u-01.sm201.iuk.edu 17870 4 5 500
2 u-02.sm201.iuk.edu 17871 6 7 500
3 u-03.sm201.iuk.edu 17872 8 9 500