when i try to execute this code ...It produces the hostunknownException....
import java.io.*;
import java.net.*;
import java.net.Socket;
public class SMTP
{
public static void main(String[] args) //throws Exception
{
String results = send("sender#somewhere.com", "localhost/localdomain", "Test Email", "<b>You got mail!</b>");
System.out.println(results);
}
public static String send(String from,String to,String subject, String message) //throws Exception
{
StringBuffer buffer = new StringBuffer();
try
{
Socket smtpSocket = new Socket("127.0.0.1",25);
DataOutputStream output = new DataOutputStream(smtpSocket.getOutputStream());
BufferedReader input =new BufferedReader(new InputStreamReader( new DataInputStream(smtpSocket.getInputStream())));
try
{
read(input, buffer);
send(output, "HELO localhost.localdomain\r\n", buffer);
read(input, buffer);
send(output, "MAIL FROM: " + from + "\r\n", buffer);
read(input, buffer);
send(output, "RCPT to: " + to + "\r\n", buffer);
read(input, buffer);
send(output, "DATA\r\n", buffer);
read(input, buffer);
send(output, "Subject: " + subject + "\r\n", buffer);
send(output, message, buffer);
send(output, "\r\n.\r\n", buffer);
read(input, buffer);
smtpSocket.close();
}
catch (IOException e)
{
System.out.println("Cannot send email as an error occurred.");
}
}
catch (Exception e)
{
System.out.println("Host unknown");
}
return buffer.toString();
}
private static void send(DataOutputStream output,String data,StringBuffer buffer) throws IOException
{
output.writeBytes(data);
buffer.append(data);
}
private static void read(BufferedReader br, StringBuffer buffer) throws IOException
{
int c;
while ((c = br.read()) != -1)
{
buffer.append((char) c);
if (c == '\n')
{
break;
}
}
}
}
Please help me.....i'm new to java...i trying to implement the simple mail transfer protocol...there is no compilation errors....when i try to execute this ...unknown host exception is produced....
You still need a smtp server running on your localhost. Like apache James. Or you could try using google ones for testing purpose.
Try with this mykong example
Related
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 have two win socket apps, server and client. The server app is at my virtual and client at host machine and the communication is OK. I am sending a ISO file (700MB) through that socket and I came across the error that received bytes are corrupt. When my file come to virtual machine, it has the original size, but the content is not OK. At the client side, I am using this code:
public class ProgramClient
{
public static void StartClient()
{
// Data buffer for incoming data.
byte[] msg;
try
{
IPAddress ipAd = IPAddress.Parse("192.168.137.71");
IPEndPoint remoteEP = new IPEndPoint(ipAd, 1234);
Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sender.Connect(remoteEP);
Console.WriteLine("Client connected to {0}", sender.RemoteEndPoint.ToString());
Console.WriteLine("Sending file...");
msg = GetBinaryFile(#"C:\TCPIP\test_big.iso");
byte[] msgLengthBytes = BitConverter.GetBytes(msg.Length-3);
int msgLength = BitConverter.ToInt32(msgLengthBytes, 0);
Console.WriteLine("int: {0}", msgLength);
Console.WriteLine("msgL size: {0}", msgLengthBytes.Length);
//join arrays, file size info, TCP header
byte[] result = new byte[msgLengthBytes.Length + msgLength];
Buffer.BlockCopy(msgLengthBytes, 0, result, 0, msgLengthBytes.Length);
Buffer.BlockCopy(msg, 3, result, msgLengthBytes.Length, msgLength);
//file extension info, TCP Header
byte extension = 2; //file extension code
byte[] newArray = new byte[result.Length + 1];
result.CopyTo(newArray, 1);
newArray[0] = extension;
result = newArray;
int bytesSent = sender.Send(result);
Console.WriteLine("result size: {0}", result.Length);
sender.Shutdown(SocketShutdown.Both);
sender.Close();
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
catch (Exception e)
{
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
}
private static byte[] GetBinaryFile(string filename)
{
byte[] bytes;
using (FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
}
return bytes;
}
public static void Main(String[] args)
{
StartClient();
}
}
At the server side I have the following code:
class ProgramServer
{
public static void Main(String[] args)
{
try
{
StartListening();
}
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
catch (Exception e)
{
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
}
public static void StartListening()
{
byte[] bytes = new Byte[1024];
while (true)
{
string outputPath = string.Empty;
outputPath = #"C:\output\output";
Console.WriteLine("Waiting for a connection...");
Socket handler = SocketInstance().Accept();
data = null;
//for the TCP header, get file extension
bytes = new byte[1];
int bytesReceivedExtension = handler.Receive(bytes);
string extension = GetExtension(bytes[0]);
outputPath = outputPath + extension;
//for the TCP header, get file size information
bytes = new byte[4];
int bytesReceived = handler.Receive(bytes);
int Lenght = BitConverter.ToInt32(bytes, 0);
Console.WriteLine("msg length: " + Lenght);
int TotalReceivedBytes = 0;
while (TotalReceivedBytes < Lenght)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
TotalReceivedBytes = TotalReceivedBytes + bytesRec;
AppendAllBytes(outputPath, bytes);
}
Console.WriteLine("Bytes received total: " + TotalReceivedBytes);
Console.WriteLine(File.Exists(outputPath) ? "File received." : "File not received.");
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
private static Socket SocketInstance()
{
IPAddress ipAd = IPAddress.Parse("192.168.137.71");
IPEndPoint localEndPoint = new IPEndPoint(ipAd, 1234);
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(localEndPoint);
listener.Listen(10);
return listener;
}
public static void AppendAllBytes(string path, byte[] bytes)
{
using (var stream = new FileStream(path, FileMode.Append))
{
stream.Write(bytes, 0, bytes.Length);
}
}
public static string GetExtension(byte extOfFile)
{
switch (extOfFile)
{
case 0:
return ".txt";
case 1:
return ".png";
case 2:
return ".iso";
default:
return "";
}
}
}
So, how can I be sure that my byte[] is OK? Because when I open that ISO file at the received side, its content is not OK. IS there some alternative for any type of file to binary conversion?
Thanks.
The framing protocol you made up seems to work like this:
0 1 2 3 4 ... N
[L][L][L][L][D][...][D]
Where L represents an 32-bit integer (in which endianness?) indicating the lenght of the Data.
First, you're sending the wrong file length:
byte[] msgLengthBytes = BitConverter.GetBytes(msg.Length-3);
Why do you subtract 3? You shouldn't. This causes the last 3 bytes to be chopped off the file.
Then when filling the message buffer, you start writing at byte 3, or the last byte of L:
Buffer.BlockCopy(msg, 3, result, msgLengthBytes.Length, msgLength);
This will cause the reader to interpret an incorrect data length. You should start at byte 4.
Third, when writing the file, you shouldn't append the entire buffer, but only the bytes that Receive() actually wrote in the buffer:
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
TotalReceivedBytes = TotalReceivedBytes + bytesRec;
AppendAllBytes(outputPath, bytes, bytesRec);
Then in that method:
public static void AppendAllBytes(string path, byte[] bytes, int bufferLength)
{
using (var stream = new FileStream(path, FileMode.Append))
{
stream.Write(bytes, 0, bufferLength);
}
}
And this is why you shouldn't write your own protocol and socket code if you don't know very well what you're doing. Leverage existing protocols and libraries instead.
Why i can not create a simple stomp client using the hornetq-core-client.2.2.21.Final.jar?
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("host", "localhost");
properties.put("port", 61612);
properties.put("protocol", "stomp");
TransportConfiguration transportConfiguration = new TransportConfiguration(NettyConnectorFactory.class.getName(), properties);
ServerLocator serverLocator = HornetQClient.createServerLocatorWithoutHA(transportConfiguration);
ClientSessionFactory clientSessionFactory = serverLocator.createSessionFactory();
ClientSession clientSession = clientSessionFactory.createSession();
clientSession.createQueue("queue", "queue", true);
ClientProducer clientProducer = clientSession.createProducer("queue");
ClientMessage clientMessage = clientSession.createMessage(true);
clientMessage.getBodyBuffer().writeString("Hello");
clientProducer.send(clientMessage);
I get the following error:
java.lang.IllegalStateException: The following keys are invalid for
configuring a connector: protocol
You should use Stomp protocol for sending messages:
public void sendViaStomp(Serializable obj, String queueName)
{
try
{
Socket socket = new Socket("127.0.0.1",61612);
String connectFrame = "CONNECT\n" +
"login: guest\n" +
"passcode: guest\n" +
"request-id: 1\n" +
"\n"+
END_OF_FRAME;
sendFrame(socket, connectFrame);
String text = (String) obj;
String messageFrame = "SEND\n" +
"destination: jms.queue." + queueName + "\n" +
"\n"+
text +
END_OF_FRAME;
sendFrame(socket, messageFrame);
System.out.println("Sent Stomp Message:" + text);
String disconnectFrame = "DISCONNECT\n" +
"\n" +
END_OF_FRAME;
sendFrame(socket, disconnectFrame);
socket.close();
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
private void sendFrame(Socket socket, String data)
{
byte[] bytes;
try
{
bytes = data.getBytes("UTF-8");
OutputStream outputStream = socket.getOutputStream();
for (int i = 0; i < bytes.length; i++)
{
outputStream.write(bytes[i]);
}
outputStream.flush();
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
The overall topic is actually like a Chat Application sending a simple string message to an aws server, which uses the message to make calculations server-side and sending a simple string message as a solution back to the client.
Server: I have written a Server Class and deployed it through eclipse to aws beanstalk. (see code Server)
Client: My android device creates a socket, establishes a successful connection to my aws beanstalk ip and 8080 port, while iterating through an endless while loop in a thread listening to incoming messages from the server. (see code Client and ClientThread)
Problem: My problem is that I don't know how to check whether the server receives the connection request and messages from the client. How do I make sure, that code on aws beanstalk actually runs in background continuously listening for incoming connections? I have deployed the code, does aws beanstalk automatically start the main method of the Server Class and runs it infinitely?
Here's the server code:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String args[]) {
ServerSocket server = null;
System.out.println("Trying to open serversocket!");
try {
server = new ServerSocket(8080);
} catch (IOException e) {
System.out.println("Error on port: 8080 " + ", " + e);
System.exit(1);
}
System.out
.println("Server setup and waiting for client connection ...");
Socket client = null;
try {
client = server.accept();
} catch (IOException e) {
System.out.println("Did not accept connection: " + e);
System.exit(1);
}
System.out
.println("Client connection accepted. Moving to local port ...");
try {
DataInputStream streamIn = new DataInputStream(
new BufferedInputStream(client.getInputStream()));
DataOutputStream streamOut = new DataOutputStream(
new BufferedOutputStream(client.getOutputStream()));
boolean done = false;
String line;
int i = 4;
while (!done) {
line = streamIn.readUTF();
if (line.equalsIgnoreCase(".bye"))
done = true;
else
System.out.println("Client says: " + line);
if (i == 4) {
streamOut
.writeUTF("Actually connected to Server with round "
+ i);
streamOut.flush();
i++;
}
}
streamIn.close();
streamOut.close();
client.close();
server.close();
} catch (IOException e) {
System.out.println("IO Error in streams " + e);
}
}
}
Here's the client code:
package com.amazon.aws.singlesensor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.util.Log;
class Client implements Runnable {
private Socket socket = null;
private InputStream streamIn = null;
private OutputStream streamOut = null;
public InputStream getStreamIn() {
return streamIn;
}
public Client(String serverName, int serverPort) {
System.out.println("Establishing connection. Please wait ...");
try {
socket = new Socket(serverName, serverPort);
Log.d("DEBUG", "Connected: " + socket);
start();
} catch (UnknownHostException uhe) {
Log.d("DEBUG", "Host unknown: " + uhe.getMessage());
} catch (IOException ioe) {
Log.d("DEBUG", "Unexpected exception: " + ioe.getMessage());
}
}
public void start() throws IOException {
streamIn = socket.getInputStream();
streamOut = socket.getOutputStream();
}
public void run() {
try {
streamOut.write(streamIn.read());
streamOut.flush();
} catch (IOException ioe) {
System.out.println("Sending error: " + ioe.getMessage());
stop();
}
}
public void handle(String msg) {
if (msg.equals(".bye")) {
System.out.println("Good bye. Press RETURN to exit ...");
stop();
} else
System.out.println(msg);
}
public void stop() {
try {
if (streamIn != null)
streamIn.close();
if (streamOut != null)
streamOut.close();
if (socket != null)
socket.close();
} catch (IOException ioe) {
System.out.println("Error closing ...");
}
}
public void send(String msg) {
PrintWriter printwriter = new PrintWriter(streamOut);
printwriter.write(msg);
printwriter.flush();
}
}
Here's the ClientThread Code
package com.amazon.aws.singlesensor;
import java.io.IOException;
import java.io.InputStream;
import android.os.Handler;
public class ClientThread extends Thread {
private Client client;
private InputStream input;
private String output;
private Handler handler;
private Runnable runner;
public ClientThread() {
}
public ClientThread(Client client, Handler handler, Runnable runner) {
this.setClient(client);
this.input = client.getStreamIn();
this.handler = handler;
this.runner = runner;
this.output = "";
}
public void run() {
int status = 0;
while (status != -1) {
try {
status = input.read();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (status != '~'){
try {
status = input.read();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
output = output + String.valueOf((char) status);
handler.post(runner);
}
output = output + "\n";
}
}
public String giveString(){
return output;
}
public void setClient(Client client) {
this.client = client;
}
public Client getClient() {
return client;
}
}
Thank you for your time!
I am trying to download a file from GWT client. At server side there is a servlet which generates content of file as per request and send it back to the client.
Test Scenarios:
Scenario 1 If I hit url of servlet directly, it always give me desired result without any problems.
Scenario 2
Using GWT client on IE8,I am able to download file without any code changes. However on some other computer as soon as I try to write file content on response output stream, I get EOF exception.
org.mortbay.jetty.EofException
at org.mortbay.jetty.HttpGenerator.flush(HttpGenerator.java:760)
at org.mortbay.jetty.AbstractGenerator$Output.flush(AbstractGenerator.java:566)
at org.mortbay.jetty.HttpConnection$Output.flush(HttpConnection.java:911)
at java.io.BufferedOutputStream.flush(Unknown Source)
atXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.doGet(ServiceDataExporterServlet.java:110)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)Creating input stream....
Code of servlet is as follows:
try
{
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
int bytesWritten=0;
while ((length = data.read(buffer)) > 0) {
bytesWritten+=length;
output.write(buffer, 0, length);
}
output.flush() // At this point I am facing EOF exception.
where data is inputStream
Via means of bytesWritten variable I have confirmed that in all the three scenarios content has been written in the same way in output stream. But not sure why it is not working in some computers.
Any points will be highly appereciated.
I do something like this to download files with GWT
In the server side:
public static void sendFileToClient(String path, String filename,
int contentLen, HttpServletRequest request,
HttpServletResponse response) throws UnsupportedEncodingException
{
String ua = request.getHeader("User-Agent").toLowerCase();
boolean isIE = ((ua.indexOf("msie 6.0") != -1) || (ua
.indexOf("msie 7.0") != -1)) ? true : false;
String encName = URLEncoder.encode(filename, "UTF-8");
// Derived from Squirrel Mail and from
// http://www.jspwiki.org/wiki/BugSSLAndIENoCacheBug
if (request.isSecure())
{
response.addHeader("Pragma", "no-cache");
response.addHeader("Expires", "-1");
response.addHeader("Cache-Control", "no-cache");
}
else
{
response.addHeader("Cache-Control", "private");
response.addHeader("Pragma", "public");
}
if (isIE)
{
response.addHeader("Content-Disposition", "attachment; filename=\"" + encName + "\"");
response.addHeader("Connection", "close");
response.setContentType("application/force-download; name=\"" + encName + "\"");
}
else
{
response.addHeader("Content-Disposition", "attachment; filename=\""
+ encName + "\"");
response.setContentType("application/octet-stream; name=\""
+ encName + "\"");
if (contentLen > 0)
response.setContentLength(contentLen);
}
try
{
FileInputStream zipIn = new FileInputStream(new File(path));
ServletOutputStream out = response.getOutputStream();
response.setBufferSize(8 * 1024);
int bufSize = response.getBufferSize();
byte[] buffer = new byte[bufSize];
BufferedInputStream bis = new BufferedInputStream(zipIn, bufSize);
int count;
while ((count = bis.read(buffer, 0, bufSize)) != -1)
{
out.write(buffer, 0, count);
}
bis.close();
zipIn.close();
out.flush();
out.close();
}
catch (FileNotFoundException e)
{
System.out.println("File not found");
}
catch (IOException e)
{
System.out.println("IO error");
}
}
I have a servlet that expects for an id and then I get the related file path and I serve it to the browser with the above code.
In the client side:
public class DownloadIFrame extends Frame implements LoadHandler,
HasLoadHandlers
{
public static final String DOWNLOAD_FRAME = "__gwt_downloadFrame";
public DownloadIFrame(String url)
{
super();
setSize("0px", "0px");
setVisible(false);
RootPanel rp = RootPanel.get(DOWNLOAD_FRAME);
if (rp != null)
{
addLoadHandler(this);
rp.add(this);
setUrl(url);
}
else
openURLInNewWindow(url);
}
native void openURLInNewWindow(String url) /*-{
$wnd.open(url);
}-*/;
public HandlerRegistration addLoadHandler(LoadHandler handler)
{
return addHandler(handler, LoadEvent.getType());
}
public void onLoad(LoadEvent event)
{
}
}
In you hosted page add this Iframe
<iframe src="javascript:''" id="__gwt_downloadFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
Then to download a file put something like this:
btnDownload.addClickHandler(new ClickHandler()
{
public void onClick(ClickEvent arg0)
{
String url = GWT.getModuleBaseURL()
+ "/downloadServlet?id=[FILE_ID]";
new DownloadIFrame(url);
}
});
I hope this helps you.
Happy coding!
It happens also if the OutputStream flushes after InputStream was closed, like this:
myInputStream.close();
myOutputStream.flush();
myOutputStream.close();
it should be like:
myOutputStream.flush();
myInputStream.close();
myOutputStream.close();
Hope it helps :-)