Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Teemu Auvinen
DTEK1066-ryhmis
Commits
d689bed9
Commit
d689bed9
authored
Dec 08, 2017
by
Teemu
Browse files
Koottu ohjelma
parent
03f21007
Changes
1
Hide whitespace changes
Inline
Side-by-side
dtek1066-ryhmis/src/fi/utu/dtek1066/JavaApplication1.java
0 → 100644
View file @
d689bed9
package
javaapplication1
;
import
java.net.*
;
import
java.io.*
;
public
class
JavaApplication1
{
public
static
void
main
(
String
[]
args
)
{
System
.
out
.
println
(
"Main begin"
);
SocketHandler
socketHandler
=
null
;
StreamHandler
streamHandler
=
null
;
try
{
socketHandler
=
new
SocketHandler
();
}
catch
(
IOException
e
)
{
System
.
err
.
println
(
"Failed to create SocketHandler object."
);
e
.
printStackTrace
();
System
.
exit
(
1
);
}
try
{
streamHandler
=
socketHandler
.
openStreamHandler
();
}
catch
(
IOException
e
)
{
System
.
err
.
println
(
"Failed to open StreamHandler."
);
e
.
printStackTrace
();
System
.
exit
(
1
);
}
int
t
=
0
;
try
{
t
=
streamHandler
.
readInt
();
System
.
err
.
println
(
"Received t = "
+
t
);
}
catch
(
IOException
e
)
{
System
.
err
.
println
(
"Failed to read int through ObjectInputStream."
);
e
.
printStackTrace
();
}
//
Runko
r
=
new
Runko
();
r
.
Runko
(
t
,
streamHandler
.
ois
,
streamHandler
.
oos
,
socketHandler
.
socket
);
new
Thread
(
r
).
start
();
//
if
(
t
<
2
||
t
>
10
)
{
System
.
err
.
println
(
"Illegal value t, sending response..."
);
try
{
streamHandler
.
writeInt
(-
1
);
}
catch
(
IOException
e
)
{
System
.
out
.
println
(
"Failed to send response for illegal value."
);
e
.
printStackTrace
();
System
.
exit
(
2
);
}
System
.
err
.
println
(
"Response sent, terminating..."
);
System
.
exit
(
2
);
}
System
.
out
.
println
(
"Main end"
);
}
}
class
Summain
implements
Runnable
{
// Summaimen prototyyppi, pääasiassa olemassa testimielessä
private
int
instance
;
private
int
[]
sum
;
private
int
[]
amo
;
private
ServerSocket
in
;
// Korvataan objectoutputstreamilla ja objectinputstreamilla tai vastaavalla oliolla
void
Summain
(
int
num
,
int
[]
summa
,
int
[]
maara
,
ServerSocket
input
)
{
instance
=
num
;
sum
=
summa
;
amo
=
maara
;
in
=
input
;
// Edelleen korvataan
}
public
void
run
(){
Socket
soketti
=
null
;
ObjectOutputStream
outee
=
null
;
ObjectInputStream
inee
=
null
;
try
{
soketti
=
in
.
accept
();
outee
=
new
ObjectOutputStream
(
soketti
.
getOutputStream
());
inee
=
new
ObjectInputStream
(
soketti
.
getInputStream
());
}
catch
(
IOException
e
){}
int
read
=
0
;
do
{
try
{
read
=
inee
.
readInt
();
}
catch
(
IOException
e
)
{}
if
(
read
!=
0
)
{
sum
[
instance
]
+=
read
;
amo
[
instance
]++;
}
}
while
(
read
!=
0
);
try
{
soketti
.
close
();
inee
.
close
();
outee
.
close
();
}
catch
(
IOException
e
)
{}
}
}
class
Runko
implements
Runnable
{
private
int
t
;
private
ObjectInputStream
input
;
private
ObjectOutputStream
output
;
private
Socket
omasoketti
;
public
void
Runko
(
int
t_
,
ObjectInputStream
input_
,
ObjectOutputStream
output_
,
Socket
omasoketti_
)
{
t
=
t_
;
input
=
input_
;
output
=
output_
;
omasoketti
=
omasoketti_
;
}
@Override
public
void
run
()
{
// Create appropriate amounts of sums and amount variables
int
[]
sums
=
new
int
[
t
];
int
[]
amounts
=
new
int
[
t
];
for
(
int
i
=
0
;
i
<
t
;
i
++)
{
//Set all above to zero
sums
[
i
]
=
0
;
amounts
[
i
]
=
0
;
}
Summain
[]
summain
=
new
Summain
[
t
];
// Luodaan t kappaletta Summainten viittauksia
ServerSocket
[]
soketti
=
new
ServerSocket
[
t
];
for
(
int
i
=
0
;
i
<
t
;
i
++)
{
//
summain
[
i
]
=
new
Summain
();
// Määritetään jokaiselle Summainviittaukselle Summain
try
{
//
soketti
[
i
]
=
new
ServerSocket
(
0
);
// Luodaan uusi ServerSocket seuraavaan vapaaseen porttiin
summain
[
i
].
Summain
(
i
,
sums
,
amounts
,
soketti
[
i
]);
// Alustetaan edellämainittu Summain
}
catch
(
IOException
e
)
{
// Otetaan kiinni IOException ServerSocketin luomisesta.
}
//
new
Thread
(
summain
[
i
]).
start
();
// Käynnistetään Summain
}
for
(
int
i
=
0
;
i
<
t
;
i
++)
{
try
{
output
.
writeInt
(
soketti
[
i
].
getLocalPort
());
// Ilmoitetaan jokaisen Summaimen paikallinen portti Y:lle
output
.
flush
();
}
catch
(
IOException
e
)
{
}
}
int
previous
=
0
;
// Käytetään integeriä previous Y:n lähettämän kysymyksen säilömiseen
do
{
//
try
{
//
omasoketti
.
setSoTimeout
(
60
*
1000
);
previous
=
input
.
readInt
();
// Luetaan previoukselle arvo inputista
Answer
a
=
new
Answer
();
// Luodaan uusi vastaajaluokka
a
.
Answer
(
previous
,
t
,
sums
,
amounts
,
output
);
// Määritellään a:lle tarvitut arvot
new
Thread
(
a
).
start
();
// Käynnistetään a
}
catch
(
IOException
e
)
{
System
.
err
.
println
(
"Seems like Y is no longer transmitting. Ending"
);
previous
=
0
;
}
//
}
while
(
previous
!=
0
);
// Tutkitaan oliko Y:n lähettämä viesti 0
for
(
int
i
=
0
;
i
<
t
;
i
++)
{
try
{
soketti
[
i
].
close
();
// Suljetaan kaikki avoimet Summainsocketit
}
catch
(
IOException
e
)
{
}
}
try
{
input
.
close
();
output
.
close
();
omasoketti
.
close
();
}
catch
(
IOException
e
){
}
}
}
class
Answer
implements
Runnable
{
int
request
;
int
t
;
int
[]
sums
;
int
[]
amounts
;
ObjectOutputStream
out
;
public
void
Answer
(
int
request_
,
int
t_
,
int
[]
sums_
,
int
[]
amounts_
,
ObjectOutputStream
out_
)
{
request
=
request_
;
t
=
t_
;
sums
=
sums_
;
amounts
=
amounts_
;
out
=
out_
;
}
@Override
public
void
run
()
{
// Vastataan asianomaisesti Y:n tiedusteluun
if
(
request
==
1
)
{
// Tutkitaan palvelimen pyyntö. Jos 1:
int
fsum
=
0
;
// Määritellään final sum, eli lopullinen summa johon halutaan sums[]-taulukon alkioiden summa
for
(
int
i
=
0
;
i
<
t
;
i
++)
{
//
fsum
+=
sums
[
i
];
// Lisätään jokaisen summainpalvelimen sums[]-alkio fsumiin niin lopputulos on kaikkien summa
}
//
try
{
//
out
.
writeInt
(
fsum
);
// Lähetetään tulos Y:lle
out
.
flush
();
// Puhdistetaan kirjoitusvirta.
}
catch
(
IOException
e
)
{
// Ei käsitellä mahdollista virhettä
}
//
}
else
if
(
request
==
2
)
{
// Jos pyyntö 2:
int
fsummain
=
0
;
// Oletetaan summaimen 0 sums[]-alkio suurimmaksi
for
(
int
i
=
1
;
i
<
t
;
i
++)
{
// tutkitaan jokaisen muun summaimen sums[]-alkio
if
(
sums
[
i
]
>
sums
[
fsummain
])
// Jos havaitaan suurempi sums[]-alkio
fsummain
=
i
;
// Tallennetaan fsummain-muuttujaan kyseisen alkion numerotunnus
}
//
try
{
//
out
.
writeInt
(
fsummain
);
// Lähetetään tulos Y:lle
out
.
flush
();
// Puhdistetaan kirjoitusvirta.
}
catch
(
IOException
e
)
{
// Ei käsitellä mahdollista virhettä
}
//
}
else
if
(
request
==
3
)
{
// Jos pyyntö 3:
int
famount
=
0
;
// Määritellään final amount kuten pyynnöllä 1 final sum
for
(
int
i
=
0
;
i
<
t
;
i
++)
{
//
famount
+=
amounts
[
i
];
// Lisätään vastaavasti famountin arvoa jokaisen summaimen saamien lukujen määrällä
}
//
try
{
//
out
.
writeInt
(
famount
);
// Lähetetään tulos Y:lle
out
.
flush
();
// Puhdistetaan kirjoitusvirta.
}
catch
(
IOException
e
)
{
// Ei käsitellä mahdollista virhettä
}
//
}
else
{
if
(
request
!=
0
)
{
// Jos pyyntö ei ollut 1,2,3 tai 0 (pääohjelma hoitaa 0:n tapauksen)
try
{
//
out
.
writeInt
(-
1
);
// Lähetetään Y:lle virhekoodi -1
out
.
flush
();
// Puhdistetaan kirjoitusvirta
}
catch
(
IOException
e
)
{
// Ei käsitellä mahdollista virhettä
}
//
}
}
}
}
class
SocketHandler
{
private
static
final
int
REMOTEPORT
=
3126
;
private
static
final
int
LOCALPORT
=
6666
;
private
static
final
int
TIMEOUTMILLIS
=
5000
;
private
static
final
int
MAXRETRIES
=
5
;
private
static
final
InetAddress
REMOTEHOST
=
bytesToAddress
(
new
byte
[]
{
127
,
0
,
0
,
1
});
/**
* Turns an array of bytes into an InetAddress.
*
* @param bytes The array to be converted.
* @return The InetAddress which is the result of this conversion, or null if the conversion
* fails.
*/
private
static
InetAddress
bytesToAddress
(
byte
[]
bytes
)
{
try
{
return
InetAddress
.
getByAddress
(
bytes
);
}
catch
(
UnknownHostException
ex
)
{
System
.
err
.
println
(
"Failed in creating InetAddress"
);
ex
.
printStackTrace
();
System
.
exit
(
3
);
}
return
null
;
}
// bytesToAddress(byte[])
private
ServerSocket
serverSocket
;
public
Socket
socket
;
/**
* Creates a new SocketHandler.
*
* @throws IOException If creating the SocketHandler fails.
*/
public
SocketHandler
()
throws
IOException
{
this
.
serverSocket
=
new
ServerSocket
(
LOCALPORT
);
this
.
serverSocket
.
setSoTimeout
(
TIMEOUTMILLIS
);
}
// SocketHandler()
/**
* Closes the resources handled by this SocketHandler.
*
* @throws IOException If closing either the Socket or the ServerSocket fails.
*/
public
void
close
()
throws
IOException
{
if
(!
this
.
socket
.
isClosed
())
{
this
.
socket
.
close
();
}
if
(!
this
.
serverSocket
.
isClosed
())
{
this
.
serverSocket
.
close
();
}
}
// close()
/**
* Uses this SocketHandler to create a StreamHandler object that contains the streams from this
* SocketHandler's socket.
*
* @throws IOException if opening one of the sockets fails.
*/
public
StreamHandler
openStreamHandler
()
throws
IOException
{
int
timesRetried
=
0
;
do
{
this
.
sendPortNumber
(
REMOTEHOST
,
REMOTEPORT
,
LOCALPORT
);
try
{
this
.
socket
=
this
.
serverSocket
.
accept
();
try
{
this
.
socket
.
setSoTimeout
(
TIMEOUTMILLIS
);
}
catch
(
SocketException
e
)
{
System
.
err
.
println
(
"Failed in setting timeout for socket."
);
e
.
printStackTrace
();
}
return
new
StreamHandler
(
new
ObjectInputStream
(
this
.
socket
.
getInputStream
()),
new
ObjectOutputStream
(
this
.
socket
.
getOutputStream
()));
}
catch
(
SocketTimeoutException
ex
)
{
System
.
err
.
println
(
"Socket timed out, trying again..."
);
timesRetried
++;
}
}
while
(
timesRetried
<
MAXRETRIES
);
if
(
timesRetried
==
MAXRETRIES
)
{
System
.
err
.
println
(
"Failed to receive connection"
);
System
.
exit
(
1
);
}
return
null
;
}
// openStreamHandler()
/**
* Sends the port number localPort to the port remotePort at remoteHost
*
* @param remoteHost The machine to which the port number needs to be sent
* @param remotePort The port on remoteHost to send to
* @param localPort The local port number to be sent to remoteHost
* @throws IOException If the transmission fails
*/
private
void
sendPortNumber
(
InetAddress
remoteHost
,
int
remotePort
,
int
localPort
)
{
try
(
DatagramSocket
dsocket
=
new
DatagramSocket
(
0
))
{
String
portNumber
=
Integer
.
toString
(
localPort
);
byte
[]
portHolder
=
portNumber
.
getBytes
();
DatagramPacket
request
=
new
DatagramPacket
(
portHolder
,
portHolder
.
length
,
remoteHost
,
remotePort
);
dsocket
.
send
(
request
);
}
catch
(
SocketException
e
)
{
System
.
err
.
println
(
"Failed in opening DatagramSocket."
);
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
System
.
err
.
println
(
"Failed in sending request packet through UDP"
);
e
.
printStackTrace
();
}
}
// sendPort(InetAddress, int, int)
}
class
StreamHandler
{
public
ObjectInputStream
ois
;
public
ObjectOutputStream
oos
;
/**
* Packs the parameters ois and oos into a StreamHandler object.
*
* @param ois The ObjectInputStream to be placed in this object.
* @param oos The ObjectOutputStream to be placed in this object.
*/
public
StreamHandler
(
ObjectInputStream
ois
,
ObjectOutputStream
oos
)
{
this
.
ois
=
ois
;
this
.
oos
=
oos
;
}
// StreamHandler(ObjectInputStream, ObjectOutputStream)
/**
* Closes the streams handled by this object.
*
* @throws IOException If closing one of the streams fails.
*/
void
close
()
throws
IOException
{
this
.
ois
.
close
();
this
.
oos
.
close
();
}
// close()
/**
* Reads an int from the input stream contained in this object.
*
* @return The int read from the stream.
* @throws IOException If reading from the stream fails.
*/
int
readInt
()
throws
IOException
{
return
this
.
ois
.
readInt
();
}
// readInt()
/**
* Write an int to the output stream contained in this object.
*
* @param n The int to be written out.
* @throws IOException If writing to the stream fails.
*/
void
writeInt
(
int
n
)
throws
IOException
{
this
.
oos
.
writeInt
(
n
);
this
.
oos
.
flush
();
}
// writeInt(int)
}
// class StreamHandler
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment