It seems like the server is not receiving the message sent from the client as it should. From my understanding the client is writing to the socket outputstream. And the server is reading from the socket inputstream. Please help.
Server Code:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
static final int DEFAULT_PORTNUMBER = 1236;
public static void main(String[] args){
int portnumber;
if(args.length >= 1){
portnumber = Integer.parseInt(args[0]);
}else{
portnumber = DEFAULT_PORTNUMBER;
}
//Setting a server socket and a possible client socket
ServerSocket server = null;
Socket client;
try{
server = new ServerSocket(portnumber);
} catch (IOException e){
e.printStackTrace();
}
while(true){
try{
System.out.println("Waiting for client...");
client = server.accept();
System.out.println("Client accepted... ");
//Read data form the client
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
while(!br.ready()){
System.out.println("No message from client");
}
String msgFromClient = br.readLine();
//System.out.println("Message received from client = " + msgFromClient);
//Send Response
if(msgFromClient != null && !msgFromClient.equalsIgnoreCase("bye")){
OutputStream clientOut = client.getOutputStream();
PrintWriter pw = new PrintWriter(clientOut, true);
String ansMsg = "Hello, " + msgFromClient;
pw.println(ansMsg);
}
if(msgFromClient != null && msgFromClient.equalsIgnoreCase("Bye")){
server.close();
client.close();
break;
}
} catch(IOException e) {
e.printStackTrace();
}
//New thread for client
/*new ServerThread(client).start();
System.out.println("Client connection accepted... ");*/
}
}
}
Client Code:
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class TCPClient {
static final int DEFAULT_PORTNUMBER = 1236;
public static void main(String args[]){
Socket client = null;
int portnumber;
//Default port number if not specified as an argument
if(args.length >= 1){
portnumber = Integer.parseInt(args[0]);
}else{
portnumber = DEFAULT_PORTNUMBER;
}
try {
String msg = "";
//Creating a client socket
client = new Socket(InetAddress.getLocalHost(), portnumber);
System.out.println("Client socket is created: " + client);
//Creating an output stream for the client socket
OutputStream clientOUt = client.getOutputStream();
PrintWriter pw = new PrintWriter(clientOUt, true);
//Creating an input stream for the client socket
InputStream clientIn = client.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(clientIn));
//Creating a buffered reader for standard input System.in
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter your name. Type Bye to exit.");
//Read data from standard input and write to output stream
msg = stdIn.readLine().trim();
pw.print(msg);
while(!br.ready()){
//System.out.println("No Input From Server");
}
//Read data from input stream of client socket
System.out.println("Message returned from the server = " + br.readLine());
pw.close();
br.close();
client.close();
//Stop operation
if (msg.equalsIgnoreCase("Bye")) {
System.exit(0);
} else {
}
} catch (IOException e) {
System.out.println("I/O error " + e);
}
}
}
Note: I did disable firewall but that did not help.
Found the answer PrintWriter or any other output stream in Java do not know "\r\n". It describes how printwriter doesn't flush properly with printwriter.print() but rather only works when you use printwriter.println().
I’m trying to send an email with the STARTTLS command. I have setup a test account in Gmail and set it up to only accept inbound email with a TLS connection.
For reasons I don’t want to go into I can’t use JavaMail or other email libraries.
I have been able to send emails to this test account with using openssl. So I know that the account has been setup properly.
Example that worked: openssl s_client -starttls smtp -crlf -connect aspmx.l.google.com:25
I also have been able to send emails to this email account using a .Net application incorporating TLS.
I know that my example (below) is not the proper way to send emails, because I’m not reacting on the server’s response, but I thought this is a good/short way to create an example to demonstrate the problem.
I have been trying for a while to get this to work. I have tried connecting with different ports (465, 587, 25) with similar results. The error that I get is on the command “AUTH LOGIN”, but I’m already not getting any response from the server at my previous command “EHLO aspmx.l.google.com”.
The error that I’m getting is: “Error: Software caused connection abort: socket write error”.
Am I on the right path to negotiating a TLS connection to transmit an email or am I missing something obvious?
Any help will be much appreciated.
Example:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.xml.bind.DatatypeConverter;
public class SendEmailWithTLSConnectionTest {
private static DataOutputStream dos;
private static BufferedReader out = null;
public static void main(String[] args) throws Exception
{
try
{
int delay = 1000;
String username = DatatypeConverter.printBase64Binary("leo#tls.calcium.co.nz".getBytes());
String password = DatatypeConverter.printBase64Binary("2wsxZAQ!".getBytes());
Socket sock = new Socket("aspmx.l.google.com", 25);
out = new BufferedReader(new InputStreamReader(sock.getInputStream()));
(new Thread(new Runnable()
{
public void run()
{
while(true)
{
try
{
if(out != null)
{
String line;
while((line = out.readLine()) != null)
{
System.out.println("SERVER: "+line);
}
}
}
catch (IOException e)
{
System.out.println("IOException SERVER! Error: " + e);
try {
Thread.sleep(1000 * 5);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
})).start();
dos = new DataOutputStream(sock.getOutputStream());
send("EHLO aspmx.l.google.com\r\n");
Thread.sleep(delay * 5);
send("STARTTLS\r\n");
Thread.sleep(delay * 5);
SSLSocket sslSocket = (SSLSocket) ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(
sock,
sock.getInetAddress().getHostAddress(),
587,
true);
sslSocket.setUseClientMode(true);
sslSocket.setEnableSessionCreation(true);
// Thread.sleep(delay * 5);
// sslSocket.startHandshake();
send("EHLO aspmx.l.google.com\r\n");
Thread.sleep(delay * 5);
send("AUTH LOGIN\r\n");
Thread.sleep(delay * 5);
send(username + "\r\n");
Thread.sleep(delay * 5);
send(password + "\r\n");
Thread.sleep(delay * 5);
send("MAIL FROM: <leo#tls.calcium.co.nz>\r\n");
Thread.sleep(delay * 5);
send("RCPT TO: <leo#tls.calcium.co.nz>\r\n");
Thread.sleep(delay * 5);
send("DATA\r\n");
Thread.sleep(delay * 5);
send("Test 1 2 3");
Thread.sleep(delay * 5);
send("\r\n.\r\n");
Thread.sleep(delay * 5);
send("QUIT\r\n");
}
catch(Exception ex)
{
System.out.println("Exception when sending out test. Error: " + ex.getMessage());
}
}
private static void send(String s) throws Exception
{
dos.writeBytes(s);
System.out.println("CLIENT: "+s);
}
}
Output:
SERVER: 220 mx.google.com ESMTP on10si24036122pac.132 - gsmtp
CLIENT: EHLO aspmx.l.google.com
SERVER: 250-mx.google.com at your service, [103.23.17.19]
SERVER: 250-SIZE 35882577
SERVER: 250-8BITMIME
SERVER: 250-STARTTLS
SERVER: 250-ENHANCEDSTATUSCODES
SERVER: 250-PIPELINING
SERVER: 250-CHUNKING
SERVER: 250 SMTPUTF8
CLIENT: STARTTLS
SERVER: 220 2.0.0 Ready to start TLS
CLIENT: EHLO aspmx.l.google.com
Exception when sending out test. Error: Software caused connection abort: socket write error
Am I on the right path to negotiating a TLS connection to transmit an email or am I missing something obvious?
You are missing important steps.
Most SMTP servers implement STARTTLS only on port 587, though some servers also implement it on port 25 as well (Gmail does). You must parse the server's EHLO response to know whether STARTTLS is allowed or not.
After you receive a successful STARTTLS response, you must initiate and complete an SSL/TLS handshake before then sending any further SMTP commands. You are not doing that step (you commented out the call to SSLSocket.startHandshake()). The server is expecting a handshake hello from you, but you are sending a new EHLO command instead, which the server interprets as a bad handshake and closes the connection, which gets reported to you when you send the AUTH LOGIN command.
Also, you are connecting to port 25, but then telling SSLSocketFactory that you connected to port 587 instead. You need to be consistent.
Also, once you have established the SSL/TLS session, you can't use the original Socket for reading/sending anymore. You would be sending unencrypted data directly to the server, and reading back the server's raw encrypted data. You must use the SSLSocket instead, so it can encrypt whatever you send and decrypt whatever you read. So, you will have to reinitialize your input/output streams accordingly (and get rid of your reading thread altogether, as it does not belong in this code. SMTP is synchronous - send a command, read a response, send a command, read a response, etc).
You need something more along the lines of this:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.xml.bind.DatatypeConverter;
public class SendEmailWithTLSConnectionTest {
private static DataOutputStream dos;
private static BufferedReader out = null;
public static void main(String[] args) throws Exception
{
try
{
String username = DatatypeConverter.printBase64Binary("leo#tls.calcium.co.nz".getBytes());
String password = DatatypeConverter.printBase64Binary("2wsxZAQ!".getBytes());
Socket sock = new Socket("aspmx.l.google.com", 587);
out = new BufferedReader(new InputStreamReader(sock.getInputStream()));
dos = new DataOutputStream(sock.getOutputStream());
if (sendCmd("EHLO aspmx.l.google.com") == 250)
{
// TODO: parse response
if (true/*response contains STARTTLS capability*/)
{
sendCmd("STARTTLS", 220);
SSLSocket sslSocket = (SSLSocket) ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(
sock,
sock.getInetAddress().getHostAddress(),
sock.getPort(),
true);
sslSocket.setUseClientMode(true);
sslSocket.setEnableSessionCreation(true);
System.out.println("CLIENT: securing connection");
sslSocket.startHandshake();
// on an initial handshake, startHandshake() blocks the calling
// thread until the handshake is finished...
System.out.println("CLIENT: secured");
sock = sslSocket;
out = new BufferedReader(new InputStreamReader(sock.getInputStream()));
dos = new DataOutputStream(sock.getOutputStream());
sendCmd("EHLO aspmx.l.google.com", 250);
}
}
else
sendCmd("HELO aspmx.l.google.com", 250);
sendCmd("AUTH LOGIN", 334);
if (sendCmd(username, new int[]{235, 334}) == 334)
sendCmd(password, 235);
sendCmd("MAIL FROM: <leo#tls.calcium.co.nz>", 250);
sendCmd("RCPT TO: <leo#tls.calcium.co.nz>", new int[]{250, 251});
sendCmd("DATA", 354);
sendLine("From: <leo#tls.calcium.co.nz>");
sendLine("To: <leo#tls.calcium.co.nz>");
sendLine("Subject: test");
sendLine("");
sendLine("Test 1 2 3");
sendCmd(".", 250);
sendCmd("QUIT", 221);
}
catch(Exception ex)
{
System.out.println("Exception when sending out test. Error: " + ex.getMessage());
}
}
private static void sendLine(String s) throws Exception
{
dos.writeBytes(s + "\r\n");
System.out.println("CLIENT: " + s);
}
private static int sendCmd(String s) throws Exception
{
sendLine(s);
String line = out.readLine();
System.out.println("SERVER: " + line);
int respCode = Integer.parseInt(line.substring(0, 3));
while ((line.length() > 3) && (line.charAt(3) == '-'))
{
line = out.readLine();
System.out.println("SERVER: " + line);
}
return respCode;
}
private static int sendCmd(String s, int expectedRespCode) throws Exception
{
int respCode = sendCmd(s);
checkResponse(respCode, expectedRespCode);
return respCode;
}
private static int sendCmd(String s, int[] expectedRespCodes) throws Exception
{
int respCode = sendCmd(s);
checkResponse(respCode, expectedRespCodes);
return respCode;
}
private static void checkResponse(int actualRespCode, int expectedRespCode)
{
if (actualRespCode != expectedRespCode)
throw new Exception("command failed");
}
private static void checkResponse(int actualRespCode, int[] expectedRespCodes)
{
for (int i = 0; i < expectedRespCodes.length; ++i)
{
if (actualRespCode == expectedRespCode)
return;
}
throw new Exception("command failed");
}
}
I have adjusted the answer from above to a working version.
I insert this below so it might be helpful to somebody else. Thank you to Remy Lebeau for your guidance.
package com.mailprimer.smtp.sender;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.xml.bind.DatatypeConverter;
public class SendEmailWithTLSConnectionTest {
private static DataOutputStream dos;
private static BufferedReader out = null;
public static void main(String[] args) throws Exception
{
try
{
String username = DatatypeConverter.printBase64Binary("leo#tls.calcium.co.nz".getBytes());
String password = DatatypeConverter.printBase64Binary("XXXXXXXXXX".getBytes());
Socket sock = new Socket("aspmx.l.google.com", 25);
out = new BufferedReader(new InputStreamReader(sock.getInputStream()));
dos = new DataOutputStream(sock.getOutputStream());
int responseCode = sendCommand("EHLO aspmx.l.google.com", 250);
if ( responseCode == 250)
{
// TODO: parse response
if (true/*response contains STARTTLS capability*/)
{
sendCmd("STARTTLS", 220);
SSLSocket sslSocket = (SSLSocket) ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(
sock,
sock.getInetAddress().getHostAddress(),
sock.getPort(),
true);
sslSocket.setUseClientMode(true);
sslSocket.setEnableSessionCreation(true);
System.out.println("CLIENT: securing connection");
sslSocket.startHandshake();
// on an initial handshake, startHandshake() blocks the calling
// thread until the handshake is finished...
System.out.println("CLIENT: secured");
sock = sslSocket;
out = new BufferedReader(new InputStreamReader(sock.getInputStream()));
dos = new DataOutputStream(sock.getOutputStream());
sendCmd("EHLO aspmx.l.google.com", 250);
}
}
else
{
sendCmd("HELO aspmx.l.google.com", 250);
}
sendCmd("MAIL FROM: <leo#tls.calcium.co.nz>", 250);
sendCmd("RCPT TO: <leo#tls.calcium.co.nz>", new int[]{250, 251});
sendCmd("DATA", 354);
sendLine("From: <leo#tls.calcium.co.nz>");
sendLine("To: <leo#tls.calcium.co.nz>");
sendLine("Subject: test");
sendLine("");
sendLine("Test 1 2 3");
sendCmd(".", 250);
sendCmd("QUIT", 221);
}
catch(Exception ex)
{
System.out.println("Exception when sending out test. Error: " + ex.getMessage());
}
}
private static void sendLine(String s) throws Exception
{
dos.writeBytes(s + "\r\n");
System.out.println("CLIENT: " + s);
}
private static int sendCommand(String s, int expectedRespCode) throws Exception
{
sendLine(s);
String line = out.readLine();
System.out.println("SERVER: " + line);
// Need to wait a little longer until the other response is finished.
Thread.sleep(100);
int respCode = Integer.parseInt(line.substring(0, 3));
if(expectedRespCode > 0)
{
while ((line.length() > 3) && ((line.charAt(3) == '-') || respCode != expectedRespCode))
{
line = out.readLine();
System.out.println("SERVER: " + line);
respCode = Integer.parseInt(line.substring(0, 3));
// Need to wait a little longer until the other response is finished.
Thread.sleep(100);
}
}
return respCode;
}
private static int sendCmd(String s, int expectedRespCode) throws Exception
{
int respCode = sendCommand(s, expectedRespCode);
checkResponse(respCode, expectedRespCode);
return respCode;
}
private static int sendCmd(String s, int[] expectedRespCodes) throws Exception
{
int respCode = sendCommand(s, 0);
checkResponse(respCode, expectedRespCodes);
return respCode;
}
private static void checkResponse(int actualRespCode, int expectedRespCode) throws Exception
{
if (actualRespCode != expectedRespCode)
throw new Exception("command failed");
}
private static void checkResponse(int actualRespCode, int[] expectedRespCodes) throws Exception
{
for (int i = 0; i < expectedRespCodes.length; ++i)
{
int expectedRespCode = expectedRespCodes[i];
if (actualRespCode == expectedRespCode)
return;
}
throw new Exception("command failed");
}
}
I am trying to figure out why the client component of the array below is out of range. I know this happens when the element of an array that you are trying to access doesn't exist but I am new to Socket Programming and trying to write my first UDP script but not sure how to deal with it.
Client side code causing error at the args[0]:
class EmployeeUDPClient{
public static void Main(string[] args){
UdpClient udpc = new UdpClient(args[0],2055); //Line causing error
IPEndPoint ep = null;
while(true){
Console.Write("Name: ");
string name = Console.ReadLine();
if(name == "") break;
byte[] sdata = Encoding.ASCII.GetBytes(name);
udpc.Send(sdata,sdata.Length);
byte[] rdata = udpc.Receive(ref ep);
string job = Encoding.ASCII.GetString(rdata);
Console.WriteLine(job);
}
}
}
This is the server side code which runs fine:
class EmployeeUDPServer{
public static void Main(){
UdpClient udpc = new UdpClient(2055);
Console.WriteLine("Server started, servicing on port 2055");
IPEndPoint ep = null;
while(true){
byte[] rdata = udpc.Receive(ref ep);
string name = Encoding.ASCII.GetString(rdata);
string job = ConfigurationSettings.AppSettings[name];
if(job == null) job = "No such employee";
byte[] sdata = Encoding.ASCII.GetBytes(job);
udpc.Send(sdata,sdata.Length,ep);
}
}
}
Any thoughts on why I get this error? I am running the 2 scripts on the same computer so could that be the reason?
The error is because you are not passing any arguments to the Main() function within your client class.
Change line:
UdpClient udpc = new UdpClient(2055);
To:
string[] host = new string[1];
host[0] = "127.0.0.1";
UdpClient udpc = new UdpClient(host);
How do I make this program exit when I run it in terminal using the Java JDK in Ubuntu?
I want to type in "end" when this program is running, but I can't get it to work.
It listens for clients and calls a thread thingy to create a socket for the new client.
I can't figure out how to make this program end. I tried everything.
I started learning java yesterday.
Please help me....
import java.net.*; //jave lib
import java.io.*; //io lib
public class MultiServerConnections { //initiate class
public static void main(String[] args) throws IOException {
int portNum = 5342; //set server port number
boolean listen = true;
System.out.println("Listening for Connections"); //print message
ServerSocket server_Socket = null; //set server_Socket to null
try {
server_Socket = new ServerSocket(portNum); //set server port
} catch (IOException e) {
System.err.println("Port " + portNum + " is unavailable"); //port is taken error
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); //set reader
String input;
//while (TCPglobals.checkRequests){
while (listen == true){
new MultiServer(server_Socket.accept()).start();
input = stdIn.readLine();
//if(TCPglobals.checkRequests == false) //|| (input = stdIn.readLine()) == "end")
if(input == "end") {
System.out.println("end connection?");
System.exit(1);
}
}//while
server_Socket.close(); //close server socket
}
}
Hey,
I am trying to run this socket programming code.
This is the code on the server side -
package sockettest;
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(139);
}
catch (IOException e)
{
System.err.println("not able to listen on port");
System.exit(1);
}
Socket clientSocket = null;
try
{
clientSocket = serverSocket.accept();
}
catch (IOException e)
{
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); // Out is Outputstream is used to write to the Client .
BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); // in is used to read the Client's input.
String inputLine, outputLine;
out.println("Hey! . Who are you?"); // Writes to client as "Hey! . Who are you?"
while ((inputLine = in.readLine()) != null)
{
// Reads the input from the Client. if it is "bye" the program ends.
if (inputLine.equalsIgnoreCase("Bye"))
{
out.println("Bye");
break;
}
else
{
out.println("Hello Mr. " + inputLine);
}
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
This is the code running on the client side -
import java.io.*;
import java.net.*;
public class Client
{
public static void main(String[] args) throws IOException {
Socket kkSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try
{
kkSocket = new Socket("192.168.2.3", 139);
out = new PrintWriter(kkSocket.getOutputStream(), true); // Out may be used to write to server from the client
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream())); // in will be used to read the lines sent by the Server.
}
catch (UnknownHostException e)
{
System.err.println("Unidentified host.");
System.exit(1);
}
catch (IOException e)
{
System.err.println("Couldn't get I/O for the connection to.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromClient;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye"))
break;
fromClient = stdIn.readLine();
if (fromClient != null) {
System.out.println("Client: " + fromClient);
out.println(fromClient);
}
}
out.close();
in.close();
stdIn.close();
kkSocket.close();
}
}
I'm running the codes on eclipse in both the client and the server side. Using netstat -an command in cmd prompt, i can see that a connection has been established between the client and the server but i cannot communicate and eclipse is not showing any output too. What seems to be wrong??
You haven't told us what the problem is. However, from a cursory glance at your code, I would advise against listening on port 139 as this is already used by NetBios under Windows and may cause a conflict.
also your Server code is missing
the initialization of inputLine,
e.g
String inputline = "";
before the while loop
keep in mind that Socket's are blocked if you read or write...
your client is reading all the time because it waits for every information on the server
until it is null
and your server also reads all the time and is waiting for any input..
so as long as server and client are waiting for input, no one will receive any data.
try to think of a protocol to communicate between the server and the client.
e.g
Sever to Client: Hello Who are you?
Client receives Data and replies: Client
Server receives Information: You Are now authorized, what ya gonna do?
and so on ^^
also out.flush() is needed to send a message