Skip to content

Commit

Permalink
Finish main parts of project.
Browse files Browse the repository at this point in the history
  • Loading branch information
iamiranjbar committed May 16, 2019
1 parent 69bc14a commit 65521b4
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 153 deletions.
2 changes: 1 addition & 1 deletion src/Receiver.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public class Receiver {
public static void main(String[] args) throws Exception {
TCPServerSocket tcpServerSocket = new TCPServerSocketImpl(1237);
TCPSocket tcpSocket = tcpServerSocket.accept();
tcpSocket.receive("receiving.mp3");
tcpSocket.receive("output.txt");
tcpSocket.close();
tcpServerSocket.close();
}
Expand Down
8 changes: 3 additions & 5 deletions src/TCPServer/TCPServerSocketImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ enum Connection{
SYN_RESEVED,
ESTABLISHED
}
private EnhancedDatagramSocket datagramSocket = null;
private EnhancedDatagramSocket datagramSocket;
private int sequenceNumber = 200;
private Connection connectionState;
private static int RTT = 10000;
Expand All @@ -38,7 +38,7 @@ private void sendSynAck(Segment segment) throws IOException {

@Override
public TCPSocket accept() throws Exception {
int pairPort = 0;
int pairPort;
int synAckIterate = 5;
Segment segment = null;
byte[] data = new byte[datagramSocket.getPayloadLimitInBytes()];
Expand All @@ -60,7 +60,6 @@ public TCPSocket accept() throws Exception {
continue;
}
segment = new Segment(p.getData());
System.out.println(segment.toString());
if (segment.isSyn() && this.connectionState == null) {
this.sendSynAck(segment);
} else if (segment.isAck() && this.connectionState == Connection.SYN_RESEVED
Expand All @@ -70,12 +69,11 @@ public TCPSocket accept() throws Exception {
break;
}
}
System.out.println(pairPort);
return new TCPSocketBinded(datagramSocket, pairPort);
}

@Override
public void close() throws Exception {
throw new RuntimeException("Not implemented!");
datagramSocket.close();
}
}
131 changes: 100 additions & 31 deletions src/TCPSocket/TCPSocketBinded.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,93 @@

import datagram.*;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.net.SocketTimeoutException;

public class TCPSocketBinded extends TCPSocket {

private int sequenceNumber = 100;
private int BUFFERSIZE = 30;
private static int RTT = 10000;
private static int segmentDataSize = 1392;
private String ip;
private int port;
private EnhancedDatagramSocket datagramSocket;
private int myPort;
private int expectedSeqNum;
private String[] deliveringData;
private Boolean[] delivered;
private BufferedWriter writer;
private int timeOutNum;
private int remainBuf;

public TCPSocketBinded(EnhancedDatagramSocket datagramSocket, int port) throws Exception {
super(datagramSocket.getLocalAddress().getHostAddress(), port);
System.out.println("binded");
super(datagramSocket.getLocalAddress().getHostAddress(), datagramSocket.getLocalPort());
this.datagramSocket = datagramSocket;
this.datagramSocket.setSoTimeout(10000);
this.timeOutNum = 0;
this.port = port;
this.ip = ip;
this.ip = "127.0.0.1";
datagramSocket.setSoTimeout(RTT);
this.deliveringData = new String[this.BUFFERSIZE];
this.delivered = new Boolean[this.BUFFERSIZE];
resetDeliverd();
String outputFileName = "output.txt";
this.writer = new BufferedWriter(new FileWriter(outputFileName, true));
this.writer.write("");
this.remainBuf = this.BUFFERSIZE;
}

@Override
public void send(String pathToFile) throws Exception {

}

private boolean isExpectedSeqNum(int sequenceNumber){
return sequenceNumber == this.expectedSeqNum;
}

private boolean inWindowSegment(int sequenceNumber){
return sequenceNumber >= this.expectedSeqNum && sequenceNumber < this.expectedSeqNum + this.BUFFERSIZE;
}

@Override
public void receive(String pathToFile) throws Exception {
while(true) {
byte[] data = new byte[datagramSocket.getPayloadLimitInBytes()];
DatagramPacket p = new DatagramPacket(data, data.length);
Date date = new Date();
String strDateFormat = "hh:mm:ss a";
DateFormat dateFormat = new SimpleDateFormat(strDateFormat);
String formattedDate= dateFormat.format(date);
System.out.println(formattedDate);
try {
datagramSocket.receive(p);
} catch (Exception e) {
continue;
}
Segment segment = new Segment(p.getData());
System.out.println(new String(segment.getDataBytes()));
Segment newSegment = new Segment(segment.getDataBytes(), false, true, datagramSocket.getLocalPort(),
this.port, 0, segment.getSequenceNumber()+1, 20);
System.out.println(newSegment.toString());
System.out.println(segment.toString());
datagramSocket.send(new DatagramPacket(newSegment.getBytes(),newSegment.getBytes().length, InetAddress.getByName(this.ip), segment.getSourcePort()));
}
while (true){
byte[] data = new byte[datagramSocket.getPayloadLimitInBytes()];
DatagramPacket packet = new DatagramPacket(data, data.length);
try {
datagramSocket.receive(packet);
} catch (SocketTimeoutException socketTimeoutException){
this.timeOutNum++;
if (timeOutNum >= 3)
break;
continue;
}
Segment segment = new Segment(packet.getData());
int segmentSequenceNumber = segment.getSequenceNumber();
if (inWindowSegment(segmentSequenceNumber)) {
String cleanedByteStream = cleanByteStream(segment.getDataBytes());
this.deliveringData[segmentSequenceNumber - this.expectedSeqNum] = cleanedByteStream;
this.delivered[segmentSequenceNumber - this.expectedSeqNum] = true;
this.remainBuf--;
if (isExpectedSeqNum(segmentSequenceNumber)) {
int deliveredCount = this.deliverData();
this.shiftData(deliveredCount);
}
}
Segment ackSegment = new Segment(false, true, datagramSocket.getLocalPort(),
this.port, 0, this.expectedSeqNum, this.remainBuf);
datagramSocket.send(new DatagramPacket(ackSegment.getBytes(), ackSegment.getBytes().length,
InetAddress.getByName(this.ip), segment.getSourcePort()));
}
}

@Override
public void close() throws Exception {

writer.close();
datagramSocket.close();
}

@Override
Expand All @@ -71,4 +100,44 @@ public long getSSThreshold() {
public long getWindowSize() {
return 0;
}

private void resetDeliverd(){
for(int i = 0; i < this.BUFFERSIZE; i++)
delivered[i] = false;
}

private int deliverData() throws IOException {
int i = 0;
for (i = 0; i < this.BUFFERSIZE; i++) {
if (delivered[i]){
writer.append(deliveringData[i]);
delivered[i] = false;
this.expectedSeqNum++;
this.remainBuf++;
}
else break;
}
return i;
}

private void shiftData(int deliveredCount){
for (int i = 0; i < this.BUFFERSIZE; i++) {
if (delivered[i]){
delivered[i] = false;
deliveringData[i - deliveredCount] = deliveringData[i];
delivered[i - deliveredCount] = true;
}
}
}

private String cleanByteStream(byte[] byteStream){
StringBuilder bytes = new StringBuilder();
for (int i = 0; i < byteStream.length; i++) {
if (byteStream[i] == '\0') {
break;
}
bytes.append((char)byteStream[i]);
}
return bytes.toString();
}
}
51 changes: 28 additions & 23 deletions src/TCPSocket/TCPSocketImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,34 +29,28 @@ enum Connection{
private int sequenceNumber = 100;
private static int RTT = 10000;
private static int segmentDataSize = 1392;
private String file;
private SenderMachine senderMachine;

public TCPSocketImpl(String ip, int port) throws Exception {
super(ip, port);
try {
Random rand = new Random();
this.myPort = 1238+rand.nextInt(50);
// this.myPort = this.freePort();
datagramSocket = new EnhancedDatagramSocket(this.myPort);
datagramSocket = new EnhancedDatagramSocket(this.myPort);
} catch (Exception e) {
Random rand = new Random();
this.myPort = 1238+rand.nextInt(50)+rand.nextInt(30);
datagramSocket = new EnhancedDatagramSocket(this.myPort);
}
this.port = port;
this.ip = ip;
this.file = "";
this.connectionState = null;
datagramSocket.setSoTimeout(RTT);
this.handshake();
}

private int freePort() throws IOException {
ServerSocket s = new ServerSocket(0);
int port = s.getLocalPort();
s.close();
return port & 0xffff;
}

private void sendSYN() throws IOException {
byte[] b = new Segment(new byte[0], true, false, this.myPort, this.port, this.sequenceNumber, 0, 0).getBytes();
datagramSocket.send(new DatagramPacket(b, b.length, InetAddress.getByName(this.ip), this.port));
Expand All @@ -76,7 +70,6 @@ private void closeUDP() throws Exception {
throw new Exception("connection is failed.");
}

// TODO: retry send ack
private void handshake() throws Exception {
int synIterate = 30;
int synAckIterate = 30;
Expand Down Expand Up @@ -124,25 +117,27 @@ private void handshake() throws Exception {
public void send(String pathToFile) throws Exception {
ArrayList<Segment> segments = new ArrayList<>();
File currentDirFile = new File("src/" + pathToFile);
char[] segmentData = new char[segmentDataSize];
BufferedReader br = new BufferedReader(new FileReader(currentDirFile));
int seqNum = 0;
while(br.read(segmentData) != -1) {
// System.out.println(segmentData);
byte[] data = new String(segmentData).getBytes();
Segment segment= new Segment(data, false, false, this.myPort, this.port, seqNum++, 0, 2);
segments.add(segment);
}
senderMachine = new SenderMachine(this.datagramSocket , segments);
while (true){
String line = br.readLine();
if (line == null)
break;
line += "\n";
file += line;
}
for (int i = 0; i < file.length(); i+= segmentDataSize){
byte[] data = getSendByteArray(i);
Segment segment = new Segment(data, false, false, this.myPort, this.port, seqNum++,
0, 2);
segments.add(segment);
}
this.senderMachine = new SenderMachine(this.datagramSocket , this, segments);
this.senderMachine.run();
}

@Override
public void receive(String pathToFile) throws Exception {
// byte[] data = new byte[datagramSocket.getPayloadLimitInBytes()];
// DatagramPacket p = new DatagramPacket(data, data.length);
// datagramSocket.receive(p);
// Segment segment = new Segment(p.getData());
// System.out.println(segment.toString());
}

@Override
Expand All @@ -159,4 +154,14 @@ public long getSSThreshold() {
public long getWindowSize() {
return (long) senderMachine.getCwnd();
}

private byte[] getSendByteArray(int index){
int start = index;
int end = 0;
if (index > file.length() - segmentDataSize)
end = file.length()-1;
else
end = index + segmentDataSize - 1;
return file.substring(start, end).getBytes();
}
}
14 changes: 13 additions & 1 deletion src/datagram/Segment.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,19 @@ public Segment(byte[] all) {
this.acknowledgmentNumber = this.getAcknowledgmentNumber(all);
this.windowSize = this.getWindowSize(all);
}


public Segment(boolean syn, boolean ack, int sourcePort, int destinationPort,
int sequenceNumber, int acknowledgmentNumber, int windowSize) {
this.dataBytes = new byte[20];
this.syn = syn;
this.ack = ack;
this.sourcePort = sourcePort;
this.destinationPort = destinationPort;
this.sequenceNumber = sequenceNumber;
this.acknowledgmentNumber = acknowledgmentNumber;
this.windowSize = windowSize;
}

public String toString() {
return "sp: " +String.valueOf(this.sourcePort)
+ " dp: " +String.valueOf(this.destinationPort)
Expand Down
31 changes: 0 additions & 31 deletions src/recieverState/RecieverMachine.java

This file was deleted.

Loading

0 comments on commit 65521b4

Please sign in to comment.