WebClub - Всероссийский Клуб Веб-разработчиков
WebClub.RU » Архив » Как послать изображение по чети используя команды Socket, InputStream иOutputStream?

Как послать изображение по чети используя команды Socket, InputStream иOutputStream?


Дата публикации: 17-03-2013

Предложение отCliff Berg

Предпологая, что вы получаете изображение с сервера server, лучший путь получить это изображение - создание объекта URL. И это для вас все. Однако я подозреваю, что тот, кто задал этот вопрос хотел выполнить запрос http; Он может быть модифицирован в другие протоколы при необходимости. Это делается так:
Создается сокет, посылается запрос в том формате, в котором его хочет сервер, слушаем ответ и сохраняем его, закрываем сокет. Вот код:


// Create a socket connection with the server
Socket socket = new Socket(hostname, port);

// Determine the socket's input and output stream handles
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());

// Write CGI-formatted command to server, requesting the data
dos.writeBytes("GET " + args[1] + " HTTP/1.0");
dos.write(0x0d);
dos.write(0x0a);
dos.write(0x0d);
dos.write(0x0a);

// Read the response, directly from the socket
long MAXLENGTH = ...the largest size the file can be...;
byte b[] = new byte[MAXLENGTH];
long c = dis.read(b, 0, MAXLENGTH);
// Note: don't make MAXLENGTH larger than read() can handle;
// you may want to add buffering to this algorithm.

// Close the socket
socket.close();

// The data we wanted is now stored in b[].

// (Note: I haven't checked this, but it should work; I've written
// other similar things.)

2.Как аплет может вызвать скрипт CGI использующий метод POST method? А метод GET?

Предложение от Georg Wedenburg

Этот код есть ни что иное, как модификация примера предоставляемого вместе с Java Tutorial form Sun. Единственное, что нужно изменить, это выбрать, какой метод использовать POST или GET.

Метод POST:
Создать URL к серверному CGI
Открыть соединение
Открыть outputstream
Создать выходную строку с форматом: varname1=varvalue1&varname2=varvalue2
и так далее, знак & это разделитель между переменными
Закрыть outputstream
Открыть inputstream
Прочитать ответ от сервреа
Закрыть inputtream.
Метод GET:
Созадть объект URL к серверу CGI
Открыть соединение
Открыть inputsream
Прочитать ответ от сервера
Закрыть inputtream.
Замечание: метод GET не требует outputstream.
Следующий пример запускает форму с методом POST, я пробовал его с кучей форм и все чудно работало.


import java.io.*;
import java.net.*;

public class TestingTheForm {

public static void main(String[] args) {
try {
URL url = new URL("TheURL");
System.err.println("URL created:" + url.toString());

URLConnection connection = url.openConnection();
System.err.println("URLConnection opened ...");

PrintStream outStream = new
PrintStream(connection.getOutputStream());
System.err.println("outStream created ...");

outStream.println("var1=value1&var2=value2&var3=value3");
System.err.println("the data printed ...");
outStream.close();
System.err.println("outStream closed ...");


DataInputStream inStream = new
DataInputStream(connection.getInputStream());
String inputLine;
System.err.println("inStream opened ...");

while ((inputLine = inStream.readLine()) != null) {
System.out.println(inputLine);
}
inStream.close();
System.err.println("inStream closed ...");

} catch (MalformedURLException me) {
System.err.println("MalformedURLException: " + me);
} catch (IOException ioe) {
System.err.println("IOException: " + ioe);
}
}

}
Предложение от Jean-Luc DELATRE

Вам нет необходимости заморачиваться с сокетами и хедерами HTTP что бы исполнить метод POST необходимо просто поддержать "Content-type" и "Content-length". Вот ниже вытяжка из моего собственного работающего аплета, который можно посмотреть на http://www.lga.jca.fr/dossier_web/jld/accueilcafe.html (все по-французски). Но он не решает проблему длинных ожидающих showDocument() (смотри http://www.tientien.com/tjn/post/index.html) там последний вопрос в "CGI, Servers"


{
.../...

if (! usePOST)
{
cgiUrl = new URL(getDocumentBase(), "cgi/bounce.cgi" + query);
debugOut("translated url: " + cgiUrl.toExternalForm());
connect = cgiUrl.openConnection();
}
else
{
cgiUrl = new URL(getDocumentBase(), "cgi/bounce.cgi");
debugOut("translated url: " + cgiUrl.toExternalForm());
connect = cgiUrl.openConnection();
connect.setDoInput(true);
connect.setDoOutput(true);
connect.setUseCaches(false);
connect.setRequestProperty ("Content-type",
"application/dont-know-what");

String request = "nom=" + name.getText() + " "
+ "email=" + email.getText() + " "
+ "options=" + options.getSelectedItem() + " "
+ "\r\n";

connect.setRequestProperty ("Content-length",
Integer.toString(request.length()));

outStream = new DataOutputStream(connect.getOutputStream());

outStream.writeBytes(request);
}

DataInputStream inStream = new
DataInputStream(connect.getInputStream());

debugOut("Content " + connect.getContentType() +
" length "
+ Integer.toString(connect.getContentLength()));

while ((inputLine = inStream.readLine()) != null) {
debugOut(inputLine);
}

if (usePOST) outStream.close();
inStream.close();
}
Предложение от Dennis M. Kowallek

Нижеследующее из "comp.lang.java" от Ronald.Tschalaer@psi.ch. Я попробовал и оно работает!
Вероятно здесь больше чем запрос http, но в основном все, что нужно это создать форму хедера (заголовка):

POST cgi-script HTTP/1.0
Content-type:
Content-length:

The data you're posting...
Вот простейший аплет, который будет соединятся с my_script.cgi, передавать данные, читать ответ и отображать его.


PostExample.java:

import java.applet.Applet;
import java.awt.*;
import java.net.*;
import java.io.*;
import java.util.*;

public class PostExample extends Applet
{
private final String script = "/cgi-bin/my_script.cgi";
private final String ctype = "application/octet-stream";
// note: on some servers this needs to be "application/x-www-form-urlencoded"
// - Courtesy, John Fallows
private String sdata = "Hello World";
private String rdata = "";
private String home;
private int port;

public void init()
{
home = getDocumentBase().getHost();
port = getDocumentBase().getPort();
if (port == -1) port = 80;
}

public void start()
{
Socket sock;
OutputStream outp;
InputStream inp;
DataOutputStream dataout;
DataInputStream datain;

rdata = "";

//create a client socket

try
sock = new Socket(home, port);
catch (Exception e)
{
rdata = e+" (socket: Host: "+home+"\tPort: "+port+")";
return;
}

// Obtain output stream to communicate with the server

try
{
outp = sock.getOutputStream();
inp = sock.getInputStream();
}
catch (Exception e)
{
rdata = e+" (getstream)";
try
sock.close();
catch (IOException ee) ;
return;
}

try
{
dataout = new DataOutputStream(outp);
datain = new DataInputStream(inp);
}
catch (Exception e)
{
rdata = e+" (Dstream)";
try
sock.close();
catch (IOException ee) ;
return;
}

// Send http request to server and get return data

try
{
// HTTP header
dataout.writeBytes("POST " + script + " HTTP/1.0\r\n");
dataout.writeBytes("Content-type: " + ctype + "\r\n");
dataout.writeBytes("Content-length: " + sdata.length() + "\r\n");
dataout.writeBytes("\r\n"); // end of header
// POST data
dataout.writeBytes(sdata);
dataout.writeBytes("\r\n");
boolean body = false;
String line;
while ((line = datain.readLine()) != null)
{
if (body)
rdata += "\n" + line;
else if (line.equals("")) // end of header
body = true;
}
}
catch (Exception e)
{
rdata = e+" (write)";
try
sock.close();
catch (IOException ee) ;
return;
}

// close up shop

try
{
dataout.close();
datain.close();
}
catch (IOException e) ;
try
sock.close();
catch (IOException e) ;
}

public void stop() {}

public void paint(Graphics g)
{
StringTokenizer st = new StringTokenizer(rdata, "\n");
int line = 1,
line_sp = getFontMetrics(getFont()).getHeight()+1;

while (st.hasMoreTokens())
{
g.drawString(st.nextToken(), 5, line*line_sp);
line++;
}
}
}
Предложение от Luc Snels

Если вы будете использовать предыдущий пример с 16-битными символьными данными (когда старшие 8 бит не нули) заменить ваш "dataout.writeBytes()" на этот метод "sendString()":
void sendString(String x){
byte bytes[]=new byte[x.length()];
x.getBytes(0,x.length(),bytes,0);
try for (int i=0; i < x.length(); i++)
dataout.writeByte(bytes[i]);
catch(Exception e);
}

3.Как получить старничку html, если сервер запрашивает аутентификацию?

Предложение от Ian Goh



/***************************************************************************
If you need to provide basic authentication information, you have to
send the WWW Server the following line (at least!)

Authorization: Basic auth_info

where auth_info is the string "username:password" encoded in the
Base64 Printable Encoding format.

I rewrote the WWW "HTUU.C" encode function in Java. I believe you
do not need any other packages (except java.lang).

Usage:

String auth_info = HTUU.encode("username:password");

*****************************************************************************/



/*
** HTUU.CLASS
**
** ACKNOWLEDGEMENT:
** Main code is taken from the HTUU.C distribution, and was originally
** written by Mark Riordan (riordanmr@clvax1.cl.msu.edu)
** and Ari Luotonen (luotonen@dxcern.cern.ch).
**
** AUTHORS:
** IG Ian Goh ian.goh@jhu.edu
**
** HISTORY:
** Converted HTUU.C "HTUU_encode" function into Java (1.0.2): IG 13 July 1996
** -------------------------------------------------------------
** File contains a routine to convert a buffer
** of bytes to RFC 1113 printable encoding format.
**
** This technique is similar to the familiar Unix uuencode
** format in that it maps 6 binary bits to one ASCII
** character (or more aptly, 3 binary bytes to 4 ASCII
** characters). However, RFC 1113 does not use the same
** mapping to printable characters as uuencode.
**
** Mark Riordan 12 August 1990 and 17 Feb 1991.
** This code is hereby placed in the public domain.
** -------------------------------------------------------------
**
**
*/

class HTUU {

static String version = "HTUU Class v1.0 7/13/96";

// the Base64 printable encoding characters
static char[] ENC = {
'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'a','b','c','d','e','f','g','h','i','j','k','l','m',
'n','o','p','q','r','s','t','u','v','w','x','y','z',
'0','1','2','3','4','5','6','7','8','9','+','/'
};

// function encode takes the "username:password" string and
// converts it into the printable encoding format

static String encode(String string) {

int i, j;
byte[] byte_array = new byte[3];
StringBuffer buf_coded = new StringBuffer();

// get length of input string
int nbytes = string.length();

for (i = 0; i < nbytes; i+= 3) {

// check to make sure we don't run off the end of input string
if (i + 3 < nbytes)
j = i + 3;
else
j = nbytes;

string.getBytes(i, j, byte_array, 0); // get bytes i..j

if (j - i == 1) {
// missing last two bytes
byte_array[1] = 0;
byte_array[2] = 0;
}

if (j - i == 2) {
// missing last byte
byte_array[2] = 0;
}

// convert the three bytes into four Base64 characters
// and append to the buf_coded string buffer
buf_coded.append(ENC[byte_array[0] >> 2]);
buf_coded.append(ENC[((byte_array[0] << 4) & 060) | ((byte_array[1] >> 4) & 017)]);
buf_coded.append(ENC[((byte_array[1] << 2) & 074) | ((byte_array[2] >> 6) & 03)]);
buf_coded.append(ENC[byte_array[2] & 077]);

} // end for loop

// If nbytes was not a multiple of 3, then we have encoded too
// many characters. Adjust appropriately.

int buf_length = buf_coded.length();

if (i == nbytes+1) {
/* There were only 2 bytes in that last group */
buf_coded.setCharAt(buf_length - 1, '=');
} else if (i == nbytes+2) {
/* There was only 1 byte in that last group */
buf_coded.setCharAt(buf_length - 1, '=');
buf_coded.setCharAt(buf_length - 2, '=');
}

// return the Base64 encoded string
return buf_coded.toString();

} // end String encode (String)

} // end Class HTUU

4.Как использовать image map с Java?

Предложение от Cliff Berg

Вот пример программы клиентского image map.


/**
* A Class to map rectangular image regions to a list of URL's.
*/

class MyURLList
{
/**
* The rectangular areas
*/

Rectangle rects[] =
{
// Create two side-by-side rectangles
new Rectangle(0, 0, 20, 20),
new Rectangle(20, 0, 20, 20)
}

/**
* The associated URL's
*/

URL urls[] =
{
// Associate a URL with each rectangular region
new URL("http://www.somewhere.com/xyz.html"),
new URL("http://www.anywhere.edu/~anybody/home.htm")
}

/**
* Method for performing the mapping
*/

public URL map(int x, int y)
{
for (int i = 0; i < rects.length; i++)
{
if (rects[i].inside(x, y)) return urls[i];
}
return null;
}
}

/**
* A canvas to server as the image to be mapped
*/

class MyCanvas extends Canvas
{
MyURLList urlList;
Applet applet; // the (top level) applet loaded by the browser

/**
* Construct the canvas
*/

public MyCanvas(MyURLList u, Applet a)
{
urlList = u;
applet = a;
resize(40, 20);
}

/**
* Catch image click events
*/

public boolean handleEvent(Event e)
{
if (e.id == Event.MOUSE_DOWN)
{
// get the coordinates, and map them to a URL...
URL url = urlList.map(e.x, e.y);

// get the new HTML page
if (url != null) applet.getAppletContext().showDocument(url);

return true;
}
return super.handleEvent(e);
}
}

/**
* The applet to be loaded by the browser
*/

public class MyApplet extends Applet
{
public MyApplet()
{
MyURLList urlList = new MyURLList();
add(new MyCanvas(urlList, this));
}
}
Вот и все!
Домен продается

Популярное

Не так давно в сети появился новый сервис, под названием Dead Man Zero. Этот сервис сделал...
Рынок социальных площадок уже давно стал стабильным. Несмотря на то, что время от времени...
Artisteer 4 – единственный в своем роде продукт, позволяющий автоматизировать работу над созданием...
Апрель 2024 (1)
Октябрь 2018 (14)
Февраль 2017 (3)
Январь 2017 (1)
Август 2016 (1)
Май 2016 (2)

Карта сайта: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41

Друзья сайта



Случайная цитата

Неизвестный автор:

"Интернет – пункт приёма, обмена и сбыта краденого остроумия."

Опрос

Как Вам новый дизайн сайта?

Отлично
Неплохо
Нормальный
Ужасно