Socket server doesn't read data a second time - java

I am trying to create an asynchronous socket server with using c#
The client socket is written in Java
The problem is that when the client connects to the server for the second time, it cannot read the message from client
I also noticed that this happens when I try to send data to the server specifically from the getKey() function
The result of the first and second connections:
server code:
public class SocketServer : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8899);
Socket socketServer = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socketServer.Bind(ipEndPoint);
socketServer.Listen(100);
while (!stoppingToken.IsCancellationRequested)
{
Socket socketClient = await socketServer.AcceptAsync();
Console.WriteLine("Client connected");
processClientTearOff(socketClient);
}
}
async Task processClientTearOff(Socket socket)
{
using (var client = new Client(socket))
await client.ProcessAsync();
}
class Client : IDisposable
{
Socket socketClient;
public Client(Socket socketClient)
{
this.socketClient = socketClient;
}
public void Dispose()
{
Console.WriteLine("Client dispose");
if (socketClient != null)
{
socketClient.Disconnect(false);
socketClient.Shutdown(SocketShutdown.Both);
socketClient.Close();
socketClient.Dispose();
socketClient = null;
}
}
bool SocketConnected()
{
if (socketClient == null || !socketClient.Connected)
return false;
bool part1 = socketClient.Poll(1000, SelectMode.SelectRead);
bool part2 = (socketClient.Available == 0);
if (part1 && part2)
return false;
else
return true;
}
public async Task ProcessAsync()
{
while (SocketConnected())
{
await JavaClient();
}
}
async Task JavaClient()
{
string a = await ReadUTF();
WriteUTF(a);
}
async Task WriteUTF(string data)
{
Console.WriteLine($"[+] Write : {data}");
byte[] bytes = Encoding.UTF8.GetBytes(data);
byte[] bytesLength = BitConverter.GetBytes(bytes.Length);
Array.Reverse(bytesLength, 0, bytesLength.Length);
await socketClient.SendAsync(bytesLength, SocketFlags.None);
await socketClient.SendAsync(bytes, SocketFlags.None);
}
async Task<string> ReadUTF()
{
byte[] buf = new byte[4];
int bytesRec = await socketClient.ReceiveAsync(buf, SocketFlags.None);
int totalBytesRec = 0;
StringBuilder builder = new StringBuilder();
if (4 == bytesRec)
{
int len = ReverseInt(buf);
buf = new byte[len];
do
{
bytesRec = await socketClient.ReceiveAsync(buf, SocketFlags.None);
totalBytesRec += bytesRec;
builder.Append(Encoding.UTF8.GetString(buf, 0, bytesRec));
} while (totalBytesRec < len && bytesRec > 0);
}
string result = builder.ToString();
Console.WriteLine($"[+] Read : {result}");
return result;
}
int ReverseInt(byte[] array)
{
var bytes = new byte[array.Length];
array.CopyTo(bytes, 0);
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes);
return BitConverter.ToInt32(bytes, 0);
}
}
}
client code:
public static void main(String[] args)
{
try
{
Socket s = new Socket(IP, PORT);
final DataInputStream in = new DataInputStream(s.getInputStream());
final DataOutputStream out = new DataOutputStream(s.getOutputStream());
String key = getKey(); // key = A5E5F7B526C52014323E17B1BAEA406C
writeUTF(out, key);
System.out.println(readUTF(in));
}
catch (Exception exception)
{
exception.printStackTrace();
}
}
public static String getKey() {
try {
MessageDigest hash = MessageDigest.getInstance("MD5");
String s = System.getenv("COMPUTERNAME") + System.getenv("PROCESSOR_IDENTIFIER")
+ System.getenv("PROCESSOR_ARCHITECTURE") + System.getenv("NUMBER_OF_PROCESSORS");
return bytesToHex(hash.digest(s.getBytes()));
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
private static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
public static void writeUTF(DataOutputStream out, String str) throws Exception {
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
out.writeInt(bytes.length);
out.write(bytes);
}
public static String readUTF(DataInputStream in) throws Exception {
int length = in.readInt();
byte[] bytes = new byte[length];
int totalBytesRec = 0;
int bytesRec = 4;
StringBuilder builder = new StringBuilder();
do {
bytesRec = in.read(bytes);
totalBytesRec += bytesRec;
builder.append(new String(bytes, 0, bytesRec, StandardCharsets.UTF_8));
} while (totalBytesRec < length && bytesRec > 0);
return builder.toString();
}

You need to change your ReadUTF method on server
async Task<string> ReadUTF()
{
byte[] buf = new byte[4];
int totalBytesRec = 0;
do
{
byte[] tmp= new byte[1];
int bytesRec = await socketClient.ReceiveAsync(tmp, SocketFlags.None);
if(bytesRec>0){
buff[totalBytesRec++]=tmp[0];
}
} while (4 == totalBytesRec);
totalBytesRec = 0;
StringBuilder builder = new StringBuilder();
int len = ReverseInt(buf);
buf = new byte[len];
do
{
bytesRec = await socketClient.ReceiveAsync(buf, SocketFlags.None);
totalBytesRec += bytesRec;
builder.Append(Encoding.UTF8.GetString(buf, 0, bytesRec));
} while (totalBytesRec < len && bytesRec > 0);
string result = builder.ToString();
Console.WriteLine($"[+] Read : {result}");
return result;
}

Related

NumberFormatException while converting the data passed from client to server by udp

I have the following code in my client class:
private void onCalculateClick() {
try {
DatagramSocket socket = new DatagramSocket(12346);
DatagramPacket datagramPacket;
InetAddress local = InetAddress.getByName("localhost");
byte[] bytes;
bytes = aTf.getText().getBytes();
datagramPacket = new DatagramPacket(bytes, bytes.length, local, 12345);
socket.send(datagramPacket);
bytes = bTf.getText().getBytes();
datagramPacket = new DatagramPacket(bytes, bytes.length, local, 12345);
socket.send(datagramPacket);
bytes = cTf.getText().getBytes();
datagramPacket = new DatagramPacket(bytes, bytes.length, local, 12345);
socket.send(datagramPacket);
datagramPacket = new DatagramPacket(bytes, bytes.length);
socket.receive(datagramPacket);
resultTf.setText(new String(datagramPacket.getData()));
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
As you can see, here I pass the data from JTextFields to the server and waiting for an answer. By default, the data is 2 in ATF, 8 in bTf and 11 in CTF (maybe it would help). And here's the code of my server:
public class UpdServer {
private double sum1 = 0;
private double sum2 = 0;
private byte[] bytes = new byte[100];
private DatagramSocket socket;
private DatagramPacket datagramPacket = new DatagramPacket(bytes, 100);
public static void main(String[] args) {
new UpdServer();
}
private UpdServer() {
try {
socket = new DatagramSocket(12345);
listen();
} catch (SocketException e) {
e.printStackTrace();
}
}
private void listen() {
int a, b, c;
try {
socket.receive(datagramPacket);
String str = new String(datagramPacket.getData());
System.out.println(str);
a = Integer.parseInt(str);
socket.receive(datagramPacket);
str = new String(datagramPacket.getData());
System.out.println(str);
b = Integer.parseInt(str);
socket.receive(datagramPacket);
str = new String(datagramPacket.getData());
System.out.println(str);
c = Integer.parseInt(str);
Thread firstSumThread = new Thread(() -> {
for (int i = a; i < b; i++) {
sum1 += (i - 1) * (i - 1);
}
});
Thread secondSumThread = new Thread(() -> {
for (int i = b; i < c; i++) {
sum2 += (double) 2 * i / (7 * i + 1);
}
});
firstSumThread.start();
secondSumThread.start();
firstSumThread.join();
secondSumThread.join();
sendBack();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
private void sendBack() {
String str = String.valueOf(sum1 - sum2);
byte[] send = str.getBytes();
try {
datagramPacket = new DatagramPacket(send, send.length, InetAddress.getByName("localhost"), 12346);
socket.send(datagramPacket);
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
But when I run the server, client, click on the Calculate button, I get the following error:
Exception in thread "main" java.lang.NumberFormatException: For input string: "2 "
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Integer.parseInt(Integer.java:652)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at com.mikhailovskii.lab2.udp.UpdServer.listen(UpdServer.java:37)
at com.mikhailovskii.lab2.udp.UpdServer.<init>(UpdServer.java:25)
at com.mikhailovskii.lab2.udp.UpdServer.main(UpdServer.java:19)
So, as I understand, it happens after converting the first passed String to int, but I cannot understand why. so, what's the matter and how can I solve this problem?
The problem is that your String contains trailing spaces: "2 ". Therefore a NumberFormatException happens when trying to convert it to Integer.
You may add the .trim() function to your Strings so that leading and trailing spaces are eliminated.
String str = new String(datagramPacket.getData());
if (str != null) {
str = str.trim();
}
a = Integer.parseInt(str);

Class MCrypt AES/CBC/NoPadding from Java (Android) to Swift 4

I've got a class MCrypt in Java (in an android App), it's working well, but i need to translate it in Swift 4.
Here my Class in Java
public class MCrypt {
private String SecretKey = "0pw3av67$979cdxf";
private Cipher cipher;
private String iv = "xe95bmad7x5432p8";
private IvParameterSpec ivspec = new IvParameterSpec(this.iv.getBytes());
private SecretKeySpec keyspec = new SecretKeySpec(this.SecretKey.getBytes(), "AES");
public MCrypt() {
try {
this.cipher = Cipher.getInstance("AES/CBC/NoPadding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e2) {
e2.printStackTrace();
}
}
public byte[] encrypt(String str) throws Exception {
if (str != null) {
if (str.length() != 0) {
try {
this.cipher.init(1, this.keyspec, this.ivspec);
return this.cipher.doFinal(padString(str).getBytes());
} catch (Exception e) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[encrypt] ");
stringBuilder.append(e.getMessage());
throw new Exception(stringBuilder.toString());
}
}
}
throw new Exception("Empty string");
}
public byte[] decrypt(String str) throws Exception {
if (str != null) {
if (str.length() != 0) {
try {
this.cipher.init(2, this.keyspec, this.ivspec);
return this.cipher.doFinal(hexToBytes(str));
} catch (Exception e) {
System.out.println(e);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[decrypt] ");
stringBuilder.append(e.getMessage());
throw new Exception(stringBuilder.toString());
}
}
}
throw new Exception("Empty string");
}
public static String bytesToHex(byte[] bArr) {
if (bArr == null) {
return null;
}
int length = bArr.length;
String str = "";
for (int i = 0; i < length; i++) {
StringBuilder stringBuilder;
if ((bArr[i] & 255) < 16) {
stringBuilder = new StringBuilder();
stringBuilder.append(str);
//stringBuilder.append(AppEventsConstants.EVENT_PARAM_VALUE_NO);
stringBuilder.append(Integer.toHexString(bArr[i] & 255));
str = stringBuilder.toString();
} else {
stringBuilder = new StringBuilder();
stringBuilder.append(str);
stringBuilder.append(Integer.toHexString(bArr[i] & 255));
str = stringBuilder.toString();
}
}
return str;
}
public static byte[] hexToBytes(String str) {
if (str == null || str.length() < 2) {
return null;
}
int length = str.length() / 2;
byte[] bArr = new byte[length];
for (int i = 0; i < length; i++) {
int i2 = i * 2;
bArr[i] = (byte) Integer.parseInt(str.substring(i2, i2 + 2), 16);
}
return bArr;
}
private static String padString(String str) {
int length = 16 - (str.length() % 16);
for (int i = 0; i < length; i++) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(str);
stringBuilder.append(' ');
str = stringBuilder.toString();
}
return str;
}}
You can use it like that :
String testst = "03e91bc1d6c14ad806832f98cf567830561460c565c9f1db426be13e86007c53d8171e1e7d7265c24ad84a0d3c4d346c59bd676ed3f2b2a6c4bde44b541c6a9697c63244c84483817b59e3dd3ac9bd76b9665b1495df06ab64939644221e58bfbf3624cc06af1679833ad8f7430a6314e3eb0a449c59a1f9ea093fc670bd7abab73f0f9ce7e1f74de6a34f4e4bbde6a8c4a44befffbdb020382730c2f99fdcc54319478168150d188d482306c6cc15252b21fc4c569d25cf5d2135b03612c73cd4f066b97b08a8bcd3f82f3158dcd692c33752d3fd0d85f22c841bf4b7ab8adeb9963bc16702baa38e041bbdab9bd7bc786fd5330d3a9d277dbe0ef331e1e5db6a4fc56b19210f694d1be6bc7939027da7fed1b8c412780daf93c033149bb2a90fcda46a8f54edaee3316622e7ec84d3ea831c724607614584aa2b7b882181d4291d0b1a2c73d34a41778125a7a44f7a";
String mastring = new String(new MCrypt().decrypt(teststring));
Result is
{"tempsnews":false,"imagenews":"","comments":"","relatednews":"","rnews":"","banned":"","banneduk":"","bannedus":"","bannedca":"","bannedau":"","bannedfr":"","bannedeg":"","bannedsa":"","bannedma":"","bannedsportfr":"","bannedbefr":"","bannedae":"","bannedflashbn":"","bannedglobal":"","bannedhmo":"","bannedng":"","bannednigeria":""}
For swift i use CryptoSwift (https://github.com/krzyzanowskim/CryptoSwift) and i start working on the decrypt function.
From the first step it looks easier than in Java but i can not make it works.
This is my method in Swift:
func aesDecrypt(encryptedString: String,key: String, iv: String) throws -> String {
let input: [UInt8] = Array(encryptedString.utf8)
let decrypted: Array<UInt8> = try AES(key: Array(key.utf8), blockMode: CBC(iv: Array(iv.utf8)), padding: .noPadding).decrypt(input)
let decryptedData = Data(decrypted)
return String(bytes: decryptedData.bytes, encoding: .utf8) ?? "Could not decrypt"
}
and you can call like htaht :
var strencrypted = "03e91bc1d6c14ad806832f98cf567830561460c565c9f1db426be13e86007c53d8171e1e7d7265c24ad84a0d3c4d346c59bd676ed3f2b2a6c4bde44b541c6a9697c63244c84483817b59e3dd3ac9bd76b9665b1495df06ab64939644221e58bfbf3624cc06af1679833ad8f7430a6314e3eb0a449c59a1f9ea093fc670bd7abab73f0f9ce7e1f74de6a34f4e4bbde6a8c4a44befffbdb020382730c2f99fdcc54319478168150d188d482306c6cc15252b21fc4c569d25cf5d2135b03612c73cd4f066b97b08a8bcd3f82f3158dcd692c33752d3fd0d85f22c841bf4b7ab8adeb9963bc16702baa38e041bbdab9bd7bc786fd5330d3a9d277dbe0ef331e1e5db6a4fc56b19210f694d1be6bc7939027da7fed1b8c412780daf93c033149bb2a90fcda46a8f54edaee3316622e7ec84d3ea831c724607614584aa2b7b882181d4291d0b1a2c73d34a41778125a7a44f7a"
var k = "0pw3av67$979cdxf" // 16 Bit Key
var iv = "xe95bmad7x5432p8" // 16 Bit Vector
do {
let deccc = try aesDecrypt(encryptedString: strencrypted, key: k, iv: iv)
print(deccc)
} catch {
print('error')
}
I missed something somewhere, but where ! Thanks in advance

No data found in socket but definitely received a response

I currently am writing a program which communicates to a server hosted on a separate device via TCP packets. Writing to the server works fine, but I never seem to be able to read the response. I am positive there is a response because when sniffing network packets, I see the incoming packet from the device, though the program never detects it.
public class SocketTest
{
private Socket socket;
private int currentSequence = 0;
public static void main(String[] args)
{
new SocketTest();
}
public SocketTest()
{
try
{
System.out.println("Connecting");
socket = new Socket("192.168.1.8", 8000);
System.out.println("Connected!");
System.out.println("Pinging...");
sendPacket(0, 3, null, 0);
System.out.println("Pinged!");
System.out.println("Reading..");
while (socket.isConnected())
{
byte[] res = new byte[84];
socket.getInputStream().read(res);
System.out.println("Read!");
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void sendPacket(int type, int command, int[] args, int length)
{
int t = 0;
currentSequence += 1000;
byte[] resultBuffer = new byte[84];
byte[] payload1 = getBytes(0x12345678);
System.arraycopy(payload1, 0, resultBuffer, t, payload1.length);
t += 4;
byte[] payload2 = getBytes(currentSequence);
System.arraycopy(payload2, 0, resultBuffer, t, payload2.length);
t += 4;
byte[] payload3 = getBytes(type);
System.arraycopy(payload3, 0, resultBuffer, t, payload3.length);
t += 4;
byte[] payload4 = getBytes(command);
System.arraycopy(payload4, 0, resultBuffer, t, payload4.length);
for (int i = 0; i < 16; i++)
{
t += 4;
int arg = 0;
if (args != null)
{
arg = args[i];
}
byte[] payloadArg = getBytes(arg);
System.arraycopy(payloadArg, 0, resultBuffer, t, payloadArg.length);
}
t += 4;
byte[] payload5 = getBytes(length);
System.arraycopy(payload5, 0, resultBuffer, t, payload5.length);
write(resultBuffer, 0, resultBuffer.length);
}
private void write(byte[] buffer, int startOffset, int length)
{
DataOutputStream out;
try
{
out = new DataOutputStream(socket.getOutputStream());
out.write(buffer, startOffset, length);
out.flush();
}
catch (IOException e)
{
e.printStackTrace();
}
}
private byte[] getBytes(int value)
{
ByteBuffer buffer = ByteBuffer.allocate(4).order(ByteOrder.nativeOrder());
buffer.putInt(value);
return buffer.array();
}
}
I've tried a bunch of different methods of reading.. Multithreading, heartbeat, etc.. But everytime I use InputStream's read() method, it blocks because there is no data to be read, and the socket is definitely open because the result isn't -1.
This is the actual read method i'm using in my program (The above code is an shortened xample)
private int read(byte[] buffer, int offset, int length)
{
int res = 0;
DataInputStream bis;
try
{
bis = new DataInputStream(socket.getInputStream());
if (bis.available() > 0)
{
System.out.println("Waiting bytes: " + bis.available());
System.out.println("buffer = [" + Arrays.toString(buffer) + "], offset = [" + offset + "], length = [" + length + "]");
res = bis.read(buffer, offset, length);
}
else
{
NTR.getLogger().debug("Available: " + bis.available());
}
}
catch (IOException e)
{
e.printStackTrace();
}
return res;
}
Interestingly, the C# version of the code works just fine.
namespace ntrclient
{
public class NtrClient
{
public delegate void LogHandler(string msg);
private readonly object _syncLock = new object();
private uint _currentSeq;
private int _heartbeatSendable;
public string Host;
private string _lastReadMemFileName;
private uint _lastReadMemSeq;
public NetworkStream NetStream;
public Thread PacketRecvThread;
public int Port;
public volatile int progress = -1;
public TcpClient Tcp;
public event LogHandler OnLogArrival;
private int ReadNetworkStream(Stream stream, byte [] buf, int length)
{
var index = 0;
var useProgress = length > 100000;
do
{
if (useProgress)
{
progress = (int) ((double) index / length * 100);
}
var len = stream.Read(buf, index, length - index);
if (len == 0)
{
Console.WriteLine("No data to be read");
return 0;
}
Console.WriteLine("Read " + len + " datas");
index += len;
} while (index < length);
progress = -1;
Console.WriteLine("Length: " + length + ", Buffer: " + buf);
return length;
}
private void PacketRecvThreadStart()
{
var buf = new byte [84];
var args = new uint [16];
var stream = NetStream;
while (true)
{
try
{
var ret = ReadNetworkStream(stream, buf, buf.Length);
if (ret == 0)
{
break;
}
var t = 0;
var magic = BitConverter.ToUInt32(buf, t);
t += 4;
var seq = BitConverter.ToUInt32(buf, t);
t += 4;
var type = BitConverter.ToUInt32(buf, t);
t += 4;
var cmd = BitConverter.ToUInt32(buf, t);
for (var i = 0; i < args.Length; i++)
{
t += 4;
args [i] = BitConverter.ToUInt32(buf, t);
}
t += 4;
var dataLen = BitConverter.ToUInt32(buf, t);
if (cmd != 0)
{
Log($"packet: cmd = {cmd}, dataLen = {dataLen}");
}
if (magic != 0x12345678)
{
Log($"broken protocol: magic = {magic}, seq = {seq}");
break;
}
if (cmd == 0)
{
if (dataLen != 0)
{
var dataBuf = new byte [dataLen];
ReadNetworkStream(stream, dataBuf, dataBuf.Length);
var logMsg = Encoding.UTF8.GetString(dataBuf);
Log(logMsg);
}
lock (_syncLock)
{
_heartbeatSendable = 1;
}
continue;
}
if (dataLen != 0)
{
var dataBuf = new byte [dataLen];
ReadNetworkStream(stream, dataBuf, dataBuf.Length);
HandlePacket(cmd, seq, dataBuf);
}
}
catch (Exception e)
{
Log(e.Message);
break;
}
}
Log("Server disconnected.");
Disconnect(false);
}
public void ConnectToServer()
{
if (Tcp != null)
{
Disconnect();
Log("Disconnected from previous server, connecting to new one");
}
new Thread(() =>
{
//Thread.CurrentThread.IsBackground = true;
Tcp = new TcpClient { NoDelay = true };
Tcp.Connect(Host, Port);
_currentSeq = 0;
NetStream = Tcp.GetStream();
_heartbeatSendable = 1;
PacketRecvThread = new Thread(PacketRecvThreadStart);
PacketRecvThread.Start();
Program.getMain().Connected = true;
Log("Server connected.");
}).Start();
}
public void Disconnect(bool waitPacketThread = true)
{
try
{
Tcp?.Close();
if (waitPacketThread)
{
PacketRecvThread?.Join();
}
// Not connected anymore
Program.getMain().Connected = false;
Log("Server disconnected.");
}
catch (Exception ex)
{
Log(ex.Message);
}
Tcp = null;
}
public void SendPacket(uint type, uint cmd, uint [] args, uint dataLen)
{
var t = 0;
_currentSeq += 1000;
var buf = new byte [84];
BitConverter.GetBytes(0x12345678).CopyTo(buf, t);
t += 4;
BitConverter.GetBytes(_currentSeq).CopyTo(buf, t);
t += 4;
BitConverter.GetBytes(type).CopyTo(buf, t);
t += 4;
BitConverter.GetBytes(cmd).CopyTo(buf, t);
for (var i = 0; i < 16; i++)
{
t += 4;
uint arg = 0;
if (args != null)
{
arg = args [i];
}
BitConverter.GetBytes(arg).CopyTo(buf, t);
}
t += 4;
BitConverter.GetBytes(dataLen).CopyTo(buf, t);
NetStream.Write(buf, 0, buf.Length);
}
public void SendHeartbeatPacket()
{
if (Tcp == null)
return;
lock (_syncLock)
{
if (_heartbeatSendable != 1)
return;
_heartbeatSendable = 0;
SendPacket(0, 0, null, 0);
}
}
}
}
I'm honestly stumped. I noticed that C#'s NetworkStream read and write methods are different from java, but I don't exactly know how different they are, or if it makes any difference.
Thanks in advance!

Successfully implemented threading, but I cannot figure out how to write results to file

So, I have the program doing what I want. Using threading to encrypt the passwords has turned a 15 minute task into a 2 minute task. However, I cannot seem to figure out how to write the encrypted passwords to a file. I figured I would have every thread store its result in an array and then I planned on writing the contents of the array out to a file to a file. This doesn't seem to be working at all and I'm not sure why.
I know the code if very sloppy, but I'm just trying to get a working solution before I try to pretty things up.
Thanks!
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.lang.Thread;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
class encryptThread extends Thread {
private Thread t;
private String threadName;
private long[] password_aes;
private String uh = "";
private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
private static final int[] IA = new int[256];
private int j = 0;
static {
Arrays.fill(IA, -1);
for (int i = 0, iS = CA.length; i < iS; i++)
IA[CA[i]] = i;
IA['='] = 0;
}
encryptThread( String name, int i){
threadName = name;
j = i;
}
public void run() {
String finalString = "";
String[] parts = threadName.split(":");
password_aes = prepare_key_pw(parts[1]);
uh = stringhash(parts[0], password_aes);
finalString = (parts[0] + ":" + parts[1] + ":" + uh + "\n");
//System.out.println(finalString);
PassArray.passwordArray[j] = finalString;
if (j == 176) {
for (int x = 0; x < 500; x++) {
System.out.println(PassArray.passwordArray[x]);
}
}
}
public void start ()
{
System.out.println("Starting " + threadName );
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
public static long[] str_to_a32(String string) {
if (string.length() % 4 != 0) {
string += new String(new char[4 - string.length() % 4]);
}
long[] data = new long[string.length() / 4];
byte[] part = new byte[8];
for (int k = 0, i = 0; i < string.length(); i += 4, k++) {
String sequence = string.substring(i, i + 4);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
baos.write(sequence.getBytes("ISO-8859-1"));
System.arraycopy(baos.toByteArray(), 0, part, 4, 4);
ByteBuffer bb = ByteBuffer.wrap(part);
data[k] = bb.getLong();
} catch (IOException e) {
data[k] = 0;
}
}
return data;
}
public static String a32_to_str(long[] data) {
byte[] part = null;
StringBuilder builder = new StringBuilder();
ByteBuffer bb = ByteBuffer.allocate(8);
for (int i = 0; i < data.length; i++) {
bb.putLong(data[i]);
part = Arrays.copyOfRange(bb.array(), 4, 8);
bb.clear();
ByteArrayInputStream bais = new ByteArrayInputStream(part);
while (bais.available() > 0) {
builder.append((char) bais.read());
}
}
return builder.toString();
}
public static byte[] aes_cbc_encrypt(byte[] data, byte[] key) {
String iv = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());
byte[] output = null;
try {
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/NOPADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
output = cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return output;
}
public static long[] aes_cbc_encrypt_a32(long[] idata, long[] ikey) {
try {
byte[] data = a32_to_str(idata).getBytes("ISO-8859-1");
byte[] key = a32_to_str(ikey).getBytes("ISO-8859-1");
byte[] encrypt = aes_cbc_encrypt(data, key);
return str_to_a32(new String(encrypt, "ISO-8859-1"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new long[0];
}
public static String base64_url_encode(String data) {
try {
data = new String(base64_url_encode_byte((data.getBytes("ISO-8859-1")),true), "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
data = data.replaceAll("\\+", "-");
data = data.replaceAll("/", "_");
data = data.replaceAll("=", "");
return data;
}
public static String a32_to_base64(long[] a) {
return base64_url_encode(a32_to_str(a));
}
public static String stringhash(String email, long[] aeskey) {
long[] s32 = str_to_a32(email);
long[] h32 = {0, 0, 0, 0};
for (int i = 0; i < s32.length; i++) {
h32[i % 4] ^= s32[i];
}
for (int r = 0; r < 0x4000; r++) {
h32 = aes_cbc_encrypt_a32(h32, aeskey);
}
long[] h32Part = new long[2];
h32Part[0] = h32[0];
h32Part[1] = h32[2];
return a32_to_base64(h32Part);
}
public static long[] prepare_key(long[] password) {
long[] pkey = {0x93C467E3, 0x7DB0C7A4, 0xD1BE3F81, 0x0152CB56};
for (int r = 0; r < 0x10000; r++) {
for (int j = 0; j < password.length; j += 4) {
long[] key = {0, 0, 0, 0};
for (int i = 0; i < 4; i++) {
if (i + j < password.length) {
key[i] = password[i + j];
}
}
pkey = aes_cbc_encrypt_a32(pkey, key);
}
}
return pkey;}
public static long[] prepare_key_pw(String password) {
return prepare_key(str_to_a32(password));
}
public final static byte[] base64_url_encode_byte(byte[] sArr, boolean lineSep){
// Check special case
int sLen = sArr != null ? sArr.length : 0;
if (sLen == 0)
return new byte[0];
int eLen = (sLen / 3) * 3; // Length of even 24-bits.
int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
byte[] dArr = new byte[dLen];
// Encode even 24-bits
for (int s = 0, d = 0, cc = 0; s < eLen;) {
// Copy next three bytes into lower 24 bits of int, paying attension to sign.
int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
// Encode the int into four chars
dArr[d++] = (byte) CA[(i >>> 18) & 0x3f];
dArr[d++] = (byte) CA[(i >>> 12) & 0x3f];
dArr[d++] = (byte) CA[(i >>> 6) & 0x3f];
dArr[d++] = (byte) CA[i & 0x3f];
// Add optional line separator
if (lineSep && ++cc == 19 && d < dLen - 2) {
dArr[d++] = '\r';
dArr[d++] = '\n';
cc = 0;
}
}
// Pad and encode last bits if source isn't an even 24 bits.
int left = sLen - eLen; // 0 - 2.
if (left > 0) {
// Prepare the int
int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
// Set last four chars
dArr[dLen - 4] = (byte) CA[i >> 12];
dArr[dLen - 3] = (byte) CA[(i >>> 6) & 0x3f];
dArr[dLen - 2] = left == 2 ? (byte) CA[i & 0x3f] : (byte) '=';
dArr[dLen - 1] = '=';
}
return dArr;
}
}
public class TestThread {
final static String OUTPUT_FILE_NAME = "C:\\combo_encrypted.txt";
public static void main(String args[]) throws IOException, Throwable {
for (int f = 0; f < 500; f++){
PassArray.passwordArray[f] = "haddy ma'am";
}
File file1 = new File("File1.txt");
File file2 = new File("File2.txt");
File file3 = new File("File3.txt");
File file4 = new File("File4.txt");
FileInputStream fis1 = null;
FileInputStream fis2 = null;
FileInputStream fis3 = null;
FileInputStream fis4 = null;
BufferedInputStream bis1 = null;
BufferedInputStream bis2 = null;
BufferedInputStream bis3 = null;
BufferedInputStream bis4 = null;
DataInputStream dis1 = null;
DataInputStream dis2 = null;
DataInputStream dis3 = null;
DataInputStream dis4 = null;
fis1 = new FileInputStream(file1);
fis2 = new FileInputStream(file2);
fis3 = new FileInputStream(file3);
fis4 = new FileInputStream(file4);
bis1 = new BufferedInputStream(fis1);
bis2 = new BufferedInputStream(fis2);
bis3 = new BufferedInputStream(fis3);
bis4 = new BufferedInputStream(fis4);
dis1 = new DataInputStream(bis1);
dis2 = new DataInputStream(bis2);
dis3 = new DataInputStream(bis3);
dis4 = new DataInputStream(bis4);
int i = 0;
while ( (dis4.available() != 0) ) {
encryptThread[] threadList = new encryptThread[4];
String combo1 = dis1.readLine();
String combo2 = dis2.readLine();
String combo3 = dis3.readLine();
String combo4 = dis4.readLine();
threadList[0] = new encryptThread(combo1, i);
threadList[1] = new encryptThread(combo2, i);
threadList[2] = new encryptThread(combo3, i);
threadList[3] = new encryptThread(combo4, i);
threadList[0].start();
threadList[1].start();
threadList[2].start();
threadList[3].start();
/*
RunnableDemo R1 = new RunnableDemo(combo1, array1, i);
RunnableDemo R2 = new RunnableDemo(combo2, array2, i);
RunnableDemo R3 = new RunnableDemo(combo3, array3, i);
RunnableDemo R4 = new RunnableDemo(combo4, array4, i);
R1.start();
R2.start();
R3.start();
R4.start();
*/
i++;
}
fis1.close();
fis2.close();
fis3.close();
fis4.close();
bis1.close();
bis2.close();
bis3.close();
bis4.close();
dis1.close();
dis2.close();
dis3.close();
dis4.close();
System.out.println(PassArray.passwordArray[5]);
}
}
class PassArray {
public static String[] passwordArray = new String[500];
}
there's a problem here where you are passing this into new Thread(). Maybe the Thread API supports it, but I don't think it's very standard.
public void start ()
{
System.out.println("Starting " + threadName );
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
as one of the commenters pointed out:
class encryptThread extends Thread
should become
class EncryptThread implements Runnable
then you do
new Thread(new EncryptThread()).start();
when you pass an instance of a class that implements Runnable, or in shorter terms, an instance of Runnable (they are the same) into the Thread constructor, then when you call .start() it actually kicks off in the .run() method of the Runnable instance.
Try to add the following codes:
PrintWriter file = new PrintWriter(new BufferedWriter(new FileWriter(OUTPUT_FILE_NAME, true)));
file.println(finalString);file.close();
...right before the line of code PassArray.passwordArray[j] = finalString; in your thread.
Edit: Remove the previous codes from the main thread.

File transfer over socket using JAVA

I was searching a code in java for sending multiple files over a socket, I found this code which consists of a TX main, a RX main and a class for all the dirty work I assume. Code runs with no errors but I have a questions for the experts,
where exactly in the code, the user types the files that he/she want to send to the server ?
And in the server main, what is the location where the server stores the received file, and with what name ?
Where exactly in this code ( TX / RX / ByteStream), should I amend to specify what file goes in ?
I would like to input the filename myself in the client (TX) side, where futher on I would include a JFileChooser for the user to select Graphically which file to send.
package file_rx;
import java.io.*;
import java.net.*;
public class File_RX implements Runnable
{
private static final int port = 4711;
private Socket socket;
public static void main(String[] _)
{
try
{
ServerSocket listener = new ServerSocket(port);
while (true)
{
File_RX file_rec = new File_RX();
file_rec.socket = listener.accept();
new Thread(file_rec).start();
}
}
catch (java.lang.Exception e)
{
e.printStackTrace(System.out);
}
}
public void run()
{
try
{
InputStream in = socket.getInputStream();
int nof_files = ByteStream.toInt(in);
for (int cur_file = 0; cur_file < nof_files; cur_file++)
{
String file_name = ByteStream.toString(in);
File file = new File(file_name);
ByteStream.toFile(in, file);
}
}
catch (java.lang.Exception e)
{
e.printStackTrace(System.out);
}
}
}
package file_tx;
import java.io.*;
import java.net.*;
public class File_TX
{
private static final int port = 4711;
private static final String host = "localhost";
public static void main(String[] args)
{
try
{
Socket socket = new Socket(host, port);
OutputStream os = socket.getOutputStream();
int cnt_files = args.length;
ByteStream.toStream(os, cnt_files);
for (int cur_file = 0; cur_file < cnt_files; cur_file++)
{
ByteStream.toStream(os, args[cur_file]);
ByteStream.toStream(os, new File(args[cur_file]));
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
package file_rx;
import java.io.*;
public class ByteStream
{
private static byte[] toByteArray(int in_int)
{
byte a[] = new byte[4];
for (int i = 0; i < 4; i++)
{
int b_int = (in_int >> (i*8)) & 255;
byte b = (byte) (b_int);
a[i] = b;
}
return a;
}
private static int toInt(byte[] byte_array_4)
{
int ret = 0;
for (int i = 0; i < 4; i++)
{
int b = (int) byte_array_4[i];
if (i < 3 && b < 0)
{
b = 256 + b;
}
ret += b << (i * 8);
}
return ret;
}
public static int toInt(InputStream in) throws java.io.IOException
{
byte[] byte_array_4 = new byte[4];
byte_array_4[0] = (byte)in.read();
byte_array_4[1] = (byte)in.read();
byte_array_4[2] = (byte)in.read();
byte_array_4[3] = (byte)in.read();
return toInt(byte_array_4);
}
public static String toString(InputStream ins) throws java.io.IOException
{
int len = toInt(ins);
return toString(ins, len);
}
private static String toString(InputStream ins, int len) throws java.io.IOException
{
String ret = new String();
for (int i = 0; i < len; i++)
{
ret += (char) ins.read();
}
return ret;
}
public static void toStream(OutputStream os, int i) throws java.io.IOException
{
byte [] byte_array_4 = toByteArray(i);
os.write(byte_array_4);
}
public static void toStream(OutputStream os, String s) throws java.io.IOException
{
int len_s = s.length();
toStream(os, len_s);
for (int i = 0; i < len_s; i++)
{
os.write((byte) s.charAt(i));
}
os.flush();
}
private static byte[] toByteArray(InputStream ins, int an_int) throws java.io.IOException
{
byte[] ret = new byte[an_int];
int offset = 0;
int numRead = 0;
int outstanding = an_int;
while ((offset < an_int) && (numRead = ins.read(ret, offset, outstanding)) > 0)
{
offset += numRead;
outstanding = an_int - offset;
}
if (offset < ret.length)
{
//throw new Exception("Could not completely read from stream, numRead =" + numRead + ", ret.lenght = " + ret.length);
}
return ret;
}
private static void toFile(InputStream ins, FileOutputStream fos, int len, int buf_size) throws java.io.IOException, java.io.FileNotFoundException
{
byte[] buffer = new byte[buf_size];
int len_read = 0;
int total_len_read = 0;
while (total_len_read + buf_size <= len)
{
len_read = ins.read(buffer);
total_len_read += len_read;
fos.write(buffer, 0, len_read);
}
if (total_len_read < len)
{
toFile(ins, fos, len - total_len_read, buf_size / 2);
}
}
private static void toFile(InputStream ins, File file, int len) throws java.io.IOException, java.io.FileNotFoundException
{
FileOutputStream fos = new FileOutputStream(file);
toFile(ins, fos, len, 1024);
}
public static void toFile (InputStream ins, File file) throws java.io.IOException, java.io.FileNotFoundException
{
int len = toInt(ins);
toFile(ins, file, len);
}
public static void toStream(OutputStream os, File file) throws java.io.IOException, java.io.FileNotFoundException
{
toStream(os, (int) file.length());
byte b[] = new byte[1024];
InputStream is = new FileInputStream(file);
int numRead = 0;
while ((numRead = is.read(b)) > 0)
{
os.write(b, 0, numRead);
}
os.flush();
}
}
The names (and paths) of the files to be transmitted are specified as arguments to the main method in the File_TX class. On the server side (File_RX class), the files will be saved relatively to the current directory of the File_RX.class file, having the same relative path as the input arguments above.

Categories