`
sqe_james
  • 浏览: 264861 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java网络编程

    博客分类:
  • Java
阅读更多

<!---->1.1    <!---->连接到服务器

telnet 这个工具,我想很多人都用过,telnet xxx.com 80 即返回该网站的html 格式的数据,在JavaSocket 类就类似于这个工具的功能。下面举个例子:

package net.socket;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.Scanner;

/**
 * 连接到某个端口服务器,并找印它所返回的信息
 * 
 * @author Janwer
 */
public class SocketTest {
	public static void main(String[] args) {
		try {
			//用于打开一个套接字
			Socket s = new Socket("www.baidu.com",80);
			try {
				InputStream inStream = s.getInputStream();
				//一个可以使用正则表达式来分析基本类型和字符串的简单文本扫描器
				Scanner in = new Scanner(inStream);

				while(in.hasNextLine())
				{
					String line = in.nextLine();
					System.out.println(line);
				}
			}finally {
				s.close();
			}
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
}
 

<!---->1.2    <!---->建立URL 连接

API   Java.net.URL

打开一个用于读取资源数据的输入流

InputStream openStream()

 

返回一个URLConnection 对象,该对象负责管理与资源之间的连接

URLConnection openConection()

 

当操作一个URLConnection 对象时,须非常小心地安排操作步骤:

1>. 调用URL 类中的openConnection 方法获得URLConnection 对象:

URLConnection connection = url.openConnection();

 

2>. 操作设置参数和一般请求属性:( 使用URLConnection 类比基本的URL 类能得到更多的控制功能)

API   Java.net.URLConnection

如果doInputtrue ,那么用户可以接收来自该URLConnection 的输入

void setDoInput(boolean doInput)

Boolean getDoInput()

 

如果doOutputtrue ,那么用户可以将输出发送到该URLConnection

Void setDoOutput(boolean doOutput)

Boolean getDoOutput()

 

属性ifModifiedSince 用于配置URLConnection 对象,使它只获取那些自从某个给定时间以来被修改过的数据,调用方法时传入一个long 型的秒数

Void setIfModifiedSince (long time)

Long getIfModifiedSince ()

 

如果useCachestrue ,那么数据可以从本地缓存中得到。注意,URLConnection 本身并不维护这个缓存,须由浏览器之类的外部程序提供。

void setUseCaches(boolean useCaches)

 

boolean getUseCaches()

 

allowUserInteractiontrue ,那么可以查询用户密码,也须由外部提供

void setAllowUserInteraction(boolean allowUserInteraction)

boolean getAllowsUserInteraction()

 

设置一个连接超时时限( 单位:毫秒) 。如果达到时限将抛出SocketTimeoutException

void setConnectTimeout(int timeout)

int getConnectTimeout()

 

读取超时时限(单位:毫秒),同样如达时限抛出SocketTimeoutException

void setReadTimeout(int timeout)

int getReadTimeout()

 

设置请求头的一个字段

void setRequestProperty(String key, String value)

 

返回请求头属性的一个映射表,相同的键对应的所有值被放置在同一个列表中

Map<String,List<String>> getRequestProperties()

 

连接远程资源并获取响应头信息

void connect()

 

返回响应的一个映射表

Map<String,List<String>> getHeaderFields()

 

得到响应头第n 个字段的键/ 值,如果n 等于0 或大于响应头字段总数,该方法返回null

String getHeaderFieldKey(int n) / String getHeaderField(int n)

 

如果知道内容长度,则返回该长度值,否则返回-1

int getContentLength()

 

获取内容的类型,比如text/plainimage/gif

String getContentType()

 

获取内容的编码,比如gzip 。这个值不太常用,因为默认的identity 编码并不是用Content-Encoding 头来设定的

String getContentEncoding()

 

获取创建日期、过期日以及最后一次被修改的日期。这些日期是国际标准时间的秒数

long getDate()

long getExpiration()

long getLastModifed()

 

返回从资源读取的信息或向资源写入信息流

InputStream getInputStream()

OutputStream getOutputStream()

 

选择适当的内容处理器,以便读取资源数据并将它转换成对象。该方法不能用于读取诸如text/plainimage/gif 之类的标准内容类型,除非你安装了自己的内容处理器

Object getContent()

 

3>. 使用 connect 方法建立到远程对象的实际连接

connection.connect();

除了与服务器建立套接字连接外,该方法还可以用于向服务器查询头信息

 

4>. 远程对象变为可用。远程对象的头字段和内容变为可访问

getHeaderFieldKey getHeaderField 两个方法列举了消息头的所有字段。

 

如下示例清单:

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

public class URLConnectionTest {
	public static void main(String[] args) {
		try {
			String urlName;
			if (args.length > 0)
				urlName = args[0];
			else
				urlName = "http://java.sun.com";

			URL url = new URL(urlName);
			URLConnection connection = url.openConnection();

			// set username, password if specified on command line

			if (args.length > 2) {
				String username = args[1];
				String password = args[2];
				String input = username + ":" + password;
				String encoding = base64Encode(input);
				connection.setRequestProperty("Authorization", "Basic " + encoding);
			}

			connection.connect();

			// print header fields

			Map<String, List<String>> headers = connection.getHeaderFields();
			for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
				String key = entry.getKey();
				for (String value : entry.getValue())
					System.out.println(key + ": " + value);
			}

			// print convenience functions

			System.out.println("----------");
			System.out.println("getContentType: " + connection.getContentType());
			System.out.println("getContentLength: " + connection.getContentLength());
			System.out.println("getContentEncoding: " + connection.getContentEncoding());
			System.out.println("getDate: " + connection.getDate());
			System.out.println("getExpiration: " + connection.getExpiration());
			System.out.println("getLastModifed: " + connection.getLastModified());
			System.out.println("----------");

			Scanner in = new Scanner(connection.getInputStream());

			// print first ten lines of contents

			for (int n = 1; in.hasNextLine() && n <= 100; n++)
				System.out.println(in.nextLine());
			if (in.hasNextLine())
				System.out.println(". . .");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Computes the Base64 encoding of a string
	 * 
	 * @param s
	 *            a string
	 * @return the Base 64 encoding of s
	 */
	public static String base64Encode(String s) {
		ByteArrayOutputStream bOut = new ByteArrayOutputStream();
		Base64OutputStream out = new Base64OutputStream(bOut);
		try {
			out.write(s.getBytes());
			out.flush();
		} catch (IOException e) {
		}
		return bOut.toString();
	}
}

/**
 * This stream filter converts a stream of bytes to their Base64 encoding.
 * 
 * Base64 encoding encodes 3 bytes into 4 characters.
 * |11111122|22223333|33444444| Each set of 6 bits is encoded according to the
 * toBase64 map. If the number of input bytes is not a multiple of 3, then the
 * last group of 4 characters is padded with one or two = signs. Each output
 * line is at most 76 characters.
 */
class Base64OutputStream extends FilterOutputStream {
	/**
	 * Constructs the stream filter
	 * 
	 * @param out
	 *            the stream to filter
	 */
	public Base64OutputStream(OutputStream out) {
		super(out);
	}

	public void write(int c) throws IOException {
		inbuf[i] = c;
		i++;
		if (i == 3) {
			super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
			super.write(toBase64[((inbuf[0] & 0x03) << 4)
					| ((inbuf[1] & 0xF0) >> 4)]);
			super.write(toBase64[((inbuf[1] & 0x0F) << 2)
					| ((inbuf[2] & 0xC0) >> 6)]);
			super.write(toBase64[inbuf[2] & 0x3F]);
			col += 4;
			i = 0;
			if (col >= 76) {
				super.write('\n');
				col = 0;
			}
		}
	}

	public void flush() throws IOException {
		if (i == 1) {
			super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
			super.write(toBase64[(inbuf[0] & 0x03) << 4]);
			super.write('=');
			super.write('=');
		} else if (i == 2) {
			super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
			super.write(toBase64[((inbuf[0] & 0x03) << 4)
					| ((inbuf[1] & 0xF0) >> 4)]);
			super.write(toBase64[(inbuf[1] & 0x0F) << 2]);
			super.write('=');
		}
	}

	private static char[] toBase64 = { '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', '+', '/' };

	private int col = 0;
	private int i = 0;
	private int[] inbuf = new int[3];
}

 

在默认情况下建立的连接只有从服务器读取信息的输入流,并没有任何执行写操作的输出流。如果想获得输出流(例如,向一个Web 服务器提交数据), 那么需要调用:connection.setDoOutput(true) 还可以设置一些请求头与请求命令,这些属性将一起被发送到服务器。

使用setRequestProperty 来设置对特定协议起作用的任何“名- 值对”。关于HTTP 请求头的格式,请参见RFC 2616 ,其中的某些参数没有被记录在文档中,它们通常在程序员之间口头传递。E.g. ,你想访问一个有密码保护的web 页,那么必须按如下步骤操作:

1>. 将用户名、冒号和密码以字符串形式连接在一起。

String input = username + “:” + password;

2>. 计算上一步骤所得字符的base64 编码。(base64 编码用于将字节流编码成可打印的ASCII 字符流)

String encoding = base64Encode(input);

3>. 调用setRequestProperty 方法,设置name 参数的值为"Authorization"value 参数的值为"Basic" + encoding ,如下:

connection.setRequestProperty("Authorization", "Basic" + encoding);

 

当然上面提及的只是一种访问有密码保护的web 页,如果想要通过FTP 访问一个有密码保护的文件,要采用一种完全不同的方法,可以直接构建一个如下格式的URL:

ftp://username:password@ftp.yourservice.com/pub/file.txt

 

 

1.3 提交表单数据

使用POST 命令时,并不需在URL 中添加任何参数,而从URLConnection 中获取输出流,将name/value 对写入该流中,需对这些值进行URL 编码,并用& 字符将它们隔开。下面将介绍这个过程:

首先创建一个URLConnection 对象

URL url = new URL(http://host/script );

URLConnection connection = url.openConnection();

 

然后调用setDoOutput 方法建立一个用于输出的连接。

connection.setDoOutput(true);

 

接着,调用getOutputStream 方法获得一个流,可以通过这个流向服务器发送数据。如果要向服务器发送文本信息,那么可以非常方便地将流包装在PrintWriter 对象中。

PrintWriter out = new PrintWriter(connection.getOutputStream());

 

现在可以向服务器发送数据了:

out.print(name1+”=” + URLEncoder.encode(value1,”UTF-8”)+”&”);

out.print(name2 + “=” URLEncoder.encode(value2,”UTF-8”));

之后,关闭输出流。

out.close();

 

最后调用getInputStream 方法读取服务器的响应。如果在读取过程中碰到脚本运行错误,那么服务器会返回一个错误页面。为了捕捉这个错误页,可以将URLConnection 对象转型为HttpURlConnection 类开调用它的getErrorStream 方法:

InputStream err = ((HttpURLConnection)connection.getErrorStream();

 

如下示例:

package net;

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

/**
 * @author Janwer
 *
 */
public class DoPostTest {
	public static void main(String[] args)throws IOException {
		final String SERVER_URL = "http://www.census.gov/cgi-bin/ipc/idbagg";
		Map<String, String> post = new HashMap<String, String>();
		post.put("tbl", "001");
		post.put("vgp", "1");
		post.put("aggtogether", "no");
		post.put("levout", "agg");
		post.put("reg", "074");
		post.put("cty","CH");
		post.put("yr", "2008");
		post.put("fdel", "b");
		post.put("deltxt", "");
		post.put("xlate", "all");
		post.put("pres", "commas");
		post.put("stubf", "all");
		try {
			String re = doPost(SERVER_URL, post);
			System.out.print(re);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
	
	public static String doPost(String urlString,
			Map<String, String> nameValuePairs) throws IOException {
		//打开链接
		URL url = new URL(urlString);
		URLConnection connection = url.openConnection();
		
		//建立一个输出流
		connection.setDoOutput(true);
		PrintWriter out = new PrintWriter(connection.getOutputStream());

		boolean first = true;
		for (Map.Entry<String, String> pair : nameValuePairs.entrySet()) {
			if (first)
				first = false;
			else
				out.print('&');
			String name = pair.getKey();
			String value = pair.getValue();
			out.print(name);
			out.print('=');
			out.print(URLEncoder.encode(value, "UTF-8"));
		}

		out.close();

		Scanner in;
		StringBuilder response = new StringBuilder();
		try {
			in = new Scanner(connection.getInputStream());
		} catch (IOException e) {  //捕捉服务器端的脚本运行异常
			if (!(connection instanceof HttpURLConnection))
				throw e;
			InputStream err = ((HttpURLConnection) connection).getErrorStream();
			if (err == null)
				throw e;
			in = new Scanner(err);
		} //开始读取服务器端的反馈信息
		while (in.hasNextLine()) {
			response.append(in.nextLine());
			response.append("\n");
		}

		in.close();
		return response.toString();
	}
}

 

API   Java.net.HttpURLConnection

InputStream getErrorStream()

返回一个流,通过这个流可以读取web 服务器的错误信息

 

API   Java.net.URLEncoder

static String encode(String s, String encoding)

采用指定的字符编码模式,对字符串s 进行编码,并返回它的URL 编码形式。在URL 编码中,’A’-‘Z’’a’-‘z’’0’-‘9’’-‘’_’’.’’*’ 等字符保持不变,空格被编码成’+’ ,所有其他字符被编码成”%XY” 形式的字节序列,其中0xXY 为该字节十六进制数。

 

API   Java.net.URLDecoder

static String decode(String s, String encoding)

采用指定编码模式对已编码字符串s 进行解码,并返回结果。

 

1.4 高级套接字编程

1.4.1 套接字超时

在实际应用中,你可能并不想从套接字读取信息,因为在数据可以被访问之前,读操作将会阻塞。如果此时主机不可达,那么你的应用将要等待很长的时间,并且因为受底层操作系统的限制而最终会导致超时。所以针对不同的应用,应该确定合理的超时时限。调用setSoTimeout 方法可以设置这个超时时限(单位:毫秒)

方式一:

Socket s = new Socket(....);

s.setSoTimeout(1000); //time out after 10 seconds

方式二:

Socket s = new Socket();

s.connect(new InetSocketAdress(host,port),timeout);

 

如果你已经为套接字设置了超时值,并且之后的读操作和写操作在没有被完成之前就超过了时间限制,那么这些操作就会抛出SocketTimeoutException 异常。你可以捕获这个异常,并对超时做出反应。

try {

       Scanner in = new Scanner(s.getInputStream());

String line = in.next();

...

}catch(InterruptedIOException exception) {

reach to timeout

}

 

1.4.2 可中断套接字

在交互式的应用中,也许会考虑为用户提供一个功能,用以取消那些看似不会成功的连接。但是,当线程因套接字长时间无法响应而发生阻塞时,无法通过调用interrupt 来解除阻塞。

为了中断套接字操作,可以使用java.nio 包提供的一个特性―――socketChannel 类,可以使用如下方法打开:

SocketChannel channel = SocketChannel.open(new InetSocketAddress(host,port));

如果不想处理缓存,可以使用Scanner 类来读取信息,因为Scanner 有一个带ReadableByteChannel 参数的构造器:Scanner in = new Scanner(channel);

通过调用静态方法Channels.newOutputStream ,可以从通道中获取输出流。

OutputStream outStream = Channels.newOutputStream(channel);

上述操作都是必须的,假设线程正在执行打开、读取或写入操作,此时如果线程中断,那么这些操作将不会陷入阻塞,而是以抛出异常的方式结束。

 

如下示例:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import javax.swing.*;

public class InterruptibleSocketTest {
	public static void main(String[] args) {
		JFrame frame = new InterruptibleSocketFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}

class InterruptibleSocketFrame extends JFrame {
	public InterruptibleSocketFrame() {
		setSize(WIDTH, HEIGHT);
		setTitle("InterruptibleSocketTest");

		JPanel northPanel = new JPanel();
		add(northPanel, BorderLayout.NORTH);

		messages = new JTextArea();
		add(new JScrollPane(messages));

		busyBox = new JCheckBox("Busy");
		northPanel.add(busyBox);

		startButton = new JButton("Start");
		northPanel.add(startButton);
		startButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				startButton.setEnabled(false);
				cancelButton.setEnabled(true);
				connectThread = new Thread(new Runnable() {
					public void run() {
						connect();
					}
				});
				connectThread.start();
			}
		});

		cancelButton = new JButton("Cancel");
		cancelButton.setEnabled(false);
		northPanel.add(cancelButton);
		cancelButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				connectThread.interrupt();
				startButton.setEnabled(true);
				cancelButton.setEnabled(false);
			}
		});
		server = new TestServer();
		new Thread(server).start();
	}

	/**
	 * Connects to the test server.
	 */
	public void connect() {
		try {
			//使用java.nio包提供的一个特性
			SocketChannel channel = SocketChannel.open(new InetSocketAddress("localhost", 8189));
			try {
				//使用Scanner可以不处理缓存问题
				in = new Scanner(channel);
				while (true) {
					if (in.hasNextLine()) {
						String line = in.nextLine();
						messages.append(line);
						messages.append("\n");
					} else
						Thread.sleep(100);
				}
			} finally {
				channel.close();
				messages.append("Socket closed\n");
			}
		} catch (IOException e) {
			messages.append("\nInterruptibleSocketTest.connect: " + e);
		} catch (InterruptedException e) {
			messages.append("\nInterruptibleSocketTest.connect: " + e);
		}
	}

	/**
	 * A multithreaded server that listens to port 8189 and sends random numbers
	 * to the client.
	 */
	class TestServer implements Runnable {
		public void run() {
			try {
				int i = 1;
				ServerSocket s = new ServerSocket(8189);

				while (true) {
					Socket incoming = s.accept();
					Runnable r = new RandomNumberHandler(incoming);
					Thread t = new Thread(r);
					t.start();
				}
			} catch (IOException e) {
				messages.append("\nTestServer.run: " + e);
			}
		}
	}

	/**
	 * This class handles the client input for one server socket connection.
	 */
	class RandomNumberHandler implements Runnable {
		/**
		 * Constructs a handler.
		 * 
		 * @param i
		 *            the incoming socket
		 */
		public RandomNumberHandler(Socket i) {
			incoming = i;
		}

		public void run() {
			try {
				//获得输出流
				OutputStream outStream = incoming.getOutputStream();
				PrintWriter out = new PrintWriter(outStream, true /* autoFlush */);
				Random generator = new Random();
				while (true) {
					if (!busyBox.isSelected())
						out.println(generator.nextInt());
					Thread.sleep(100);
				}
			} catch (IOException e) {
				messages.append("\nRandomNumberHandler.run: " + e);
			} catch (InterruptedException e) {
				messages.append("\nRandomNumberHandler.run: " + e);
			}
		}

		private Socket incoming;
	}

	private Scanner in;
	private PrintWriter out;
	private JButton startButton;
	private JButton cancelButton;
	private JCheckBox busyBox;
	private JTextArea messages;
	private TestServer server;
	private Thread connectThread;

	public static final int WIDTH = 300;
	public static final int HEIGHT = 300;
}

 

1.4.3 半关闭

当客户端程序发送一个请求给服务器时,服务器必须能够确定该请求何时结束。因此,许多网络协议都是面向行的。其他一些协议则包含一个消息头用以指明请求数据的大小。否则要想表示请求数据的结束将比向文件写入数据更加困难。写一个文件时,只需在数据写入后关闭文件即可。但是如果关闭一个套接字,那么将立刻断开与服务器的连接。

使用半关闭的方法就可以解决上述问题。可以通过关闭一个套接字的输出流来表示发送给服务器的请求数据已经结束,但是必须保留输入流打开用以读取服务器的反馈信息。

如下代码淙了如何在客户端使用半关闭方法:

 

Socket socket = new Socket(host,port);

Scanner in = new Scanner(socket.getInputStream());

PrintWriter writer = new PrintWriter(socket.getOutputStream());

//send request data

writer.print(…);

writer.flush();

socket.shutdownOutput();

//noew cocket is half closed read response data

while((in.hasNextLine()) != null) {

String line = in.nextLine();

…}

Socket.close();

 

服务器端将读取输入信息,直到到达输入流的结尾。

当然,该协议只适用于一站式的服务,例如HTTP 服务,在这种服务中,客户端连接服务器,发送一个请求,捕获响应信息,然后断开连接。

 

1.4.4 因特网地址

这里介绍的仅适用于TCP 网络协议。TCP 可以在两台计算机之间建立可靠连接。Java 平台也支持UDP 协议,该协议可以用于发送数据包,所需开销要比TCP 少得多。但数据包是随机传递的,传输过程中可能丢失。UDP 要求数据包的接受者对它们进行排序,并请求发送者重新发送。UDP 比较适合于那些可以忍受数据包丢失的应用,例如音频流和视频流等。

 

如下示例:

import java.net.*;

public class InetAddressTest {
	public static void main(String[] args) {
		try {
			if (args.length > 0) {
				String host = args[0];
				InetAddress[] addresses = InetAddress.getAllByName(host);
				for (InetAddress a : addresses)
					System.out.println(a);
			} else {
				InetAddress localHostAddress = InetAddress.getLocalHost();
				System.out.println(localHostAddress);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

API   Java.net.InetAddress

为给定的主机名,创建一个InetAddress 对象或者一个包含了该主机名所对应的所有因特网地址的数组。

static InetAddress getByName(String host)

static InetAddress[] getAllByName(String host)

 

为本地主机创建一个InetAddress 对象

Static InetAddress getLocalHost()

 

返回一个包含数字型地址的字节数据

Byte[] getAddress()

 

返回一个由十进制数组成的字符串,各数字间用圆点符号隔开,例如,”132.134.4.120”.

String getHostAddress()

 

返回主机名

String getHostName()

 

API   Java.net.Socket

创建一个还未被连接的套接字

socket()

 

将该套接字连接到给定地址

void connect(SocketAddress address)

 

将套接字连接到给定的地址,如果给定的时间内没有响应,则返回

void connect(SocketAddress address,int timeoutInMilliseconds)

如果该套按字已经连接,则返回true

boolean isConnected()

 

如果套按字已经被关闭,则返回true

boolean isClosed()

 

在该套接字上设置读请求的阻塞时间。如果超出给定时间,则抛出一个InterruptedIOException 异常

void setSoTimeout(int timeoutInMilliseconds)

 

将输出 / 输入流设为“流结束”

void shutdownOutput()

void shutdownInput()

 

如果输出/ 输入已被关闭,则返回true

Boolean isOutputShutdown()

Boolean isInputShutdown()

 

API   Java.net.InetSocketAddress

通过主机和端口参数创建一个地址对象,并在创建过程中解析主机名。如果主机名不能被解析,那么该地址对象的unresolved 属性将被设为true

InetSocketAddress(String hostname, int port)

 

如果不能解析该地址对象,则返回true

boolean isUnresolved()

 

API   Java.nio.channels.SocketChannel

打开一个套按字通道,并将其连接到远程地址

static SocketChannel open(SocketAddress address)

 

API   Java.nio.channels.Channels

创建一输入/ 输出流,从指定的通道读取数据

static InputStream new InputStream(ReadableByteChannel channel)

static OutputStream newOutputStream(WritableByteChannel channel)

 

 

 

分享到:
评论

相关推荐

    Java网络编程案例教程习题参考答案 .pdf

    Java网络编程案例教程习题参考答案 Java_network_programming是Java编程语言中一个基础组件,用于实现网络通信。以下是Java网络编程案例教程习题参考答案中涉及到的知识点: 1. Socket编程:Socket是Java网络编程...

    Java网络编程/Java网络编程实例

    Java网络编程是Java开发中的重要领域,它涵盖了网络应用程序的设计、实现和调试。在这个主题下,我们可以探讨多个关键知识点: 1. **Java Socket编程**:Java的Socket类提供了基于TCP/IP协议的网络通信能力。通过...

    java网络编程第四版pdf

    《Java网络编程(第四版)》是一本深入探讨Java在互联网环境下的编程技术的经典书籍。本书旨在帮助读者理解和掌握如何利用Java语言进行高效、安全的网络通信。书中内容覆盖了从基本的网络概念到复杂的多线程编程,是...

    Java网络编程期末考试复习题库+答案

    Java网络编程是计算机科学中的一个重要领域,特别是在软件开发中,它涉及到如何通过网络进行数据传输和通信。在Java中,网络编程主要依赖于Java的Socket编程、ServerSocket、URL类以及NIO(非阻塞I/O)等核心API。这...

    Java网络编程实验报告.pdf

    "Java网络编程实验报告" 本实验报告主要介绍了Java网络编程的基本概念和实现方法,通过设计和实现一个简单的客户端/服务器应用程序,了解Java网络编程的基本原理和实现方法。 知识点1:Java 网络编程基础 Java ...

    java网络编程

    在本资料中,《Java网络编程》第三版提供了深入浅出的讲解,旨在帮助开发者提升对这一领域的理解。 1. **基础概念**: - **网络模型**:Java网络编程基于OSI七层模型和TCP/IP四层模型。理解这些模型有助于理解网络...

    Java网络编程(第4版)PDF

    《Java网络编程(第4版)》是一本深入探讨Java平台上的网络编程技术的专业书籍,适合想要提升Java通讯技术的学者阅读。此书全面覆盖了Java网络编程的基础和高级概念,帮助开发者理解如何利用Java语言构建高效、可靠的...

    [Java网络编程(第3版,2004)].(Java.Network.Prog.epub

    Java网络编程

    Java网络编程实践课程设计报告.pdf

    Java 网络编程实践课程设计报告 这是一份 Java 网络编程实践课程设计报告,旨在帮助学生掌握 Java 编程语言、图形化界面、多线程、网络和数据库等技术,并提高动手实践能力和书本知识学习。该课程设计报告涵盖了 ...

    Java网络编程实例(随书源代码)

    Java网络编程是开发分布式应用程序的关键技术,它允许程序通过网络发送和接收数据。《Java网络编程实例》这本书的源代码提供了丰富的示例,帮助读者深入理解这一领域。本压缩包包含的源代码覆盖了Java网络编程的各种...

    Java网络编程精解(孙卫琴)电子教案

    《Java网络编程精解》是孙卫琴老师的一本经典教程,主要涵盖了Java语言在网络编程领域的深度解析。这本书深入浅出地介绍了如何使用Java进行网络通信,包括基本的TCP/IP协议、套接字编程、多线程技术以及HTTP、FTP等...

    java网络编程.pdf

    java网络编程.pdf

    《Java网络编程实例:Java网络编程实例》

    Java网络编程是开发分布式应用程序的关键技术,它使得Java程序能够与其他设备、系统和服务进行通信。本书《Java网络编程实例:Java网络编程实例》显然聚焦于通过实际案例来教授这一核心技能。以下是一些主要的知识点...

    Java网络编程资料

    Java网络编程是开发分布式应用程序的关键技术,它允许Java程序与其他计算机进行通信,实现数据的交换。这份"Java网络编程资料"包含三个重要的学习资源:关于Socket套接字的"Java套接字编程.chm"、关于网络协议特别是...

    Java网络编程.chm

    本资源为"Java网络编程.chm",是一本关于Java网络编程的电子书,以实例驱动的方式深入讲解了相关知识。 首先,我们要理解Java在网络编程中的基础——IO流。Java中的IO流分为字节流和字符流,它们用于读写数据,包括...

    java网络编程源码

    Java网络编程是Java开发中的重要领域,它涵盖了网络通信的所有基本概念和技术,包括TCP/IP协议栈、套接字(Socket)编程、多线程、数据传输格式等。孙卫琴的《java网络编程》一书深入浅出地讲解了这些核心概念,并...

    JAVA网络编程大全,pdf版

    《JAVA网络编程大全》是一本全面且深入介绍Java网络编程技术的权威著作,旨在帮助读者掌握Java在构建网络应用程序中的核心概念和实践技巧。PDF版的书籍为学习者提供了便捷的电子阅读体验,随时随地都能深化对Java...

    java网络编程 PPT

    Java网络编程是Java开发中的重要领域,主要用于实现应用程序之间的通信,包括客户端-服务器架构、分布式系统以及互联网数据传输。这份“java网络编程 PPT”来自清华大学,无疑为学习这一主题提供了权威的参考资料。...

    java网络编程经典的学习书籍

    《Java网络编程》是编程领域的经典著作,尤其对于学习Java网络编程的初学者及进阶者来说,这本书具有很高的参考价值。它详细介绍了如何利用Java语言进行网络通信,涵盖了网络编程的基本概念、协议以及实现方法。 一...

Global site tag (gtag.js) - Google Analytics