java-网络编程

java程序设计之网络编程

网络编程简介

网络编程是指通过编程方式实现两个(或多个)设备之间的数据传输

  • 网络编程是基于“请求-响应”模式的:网络中某一端发出请求,另一端接收到请求后,响应请求方的请求
  • “请求方”称之为客户端,“响应方”称之为服务器端
  • 网络编程在客户端和服务器端之间传输数据可以采用TCP方式,也可以采用UDP方式
    网络编程开发模式
  • 客户端/服务器端模式(C/S模式):对于不同的服务器端程序建立不同的客户端程序
  • 浏览器/服务器端模式(B/S模式):对于不同的服务器端程序使用统一的“客户端”(即浏览器)即可

java网络编程核心类

Java语言中,实现网络编程需要使用两个核心类包:

  • java.net.*:网络类包,涵盖常用网络操作类
  • java.io.*:数据消息传输包,在网络双方进行数据传递需要使用该包中的类
    ###URL及应用
    使用Socket进行网络编程,从网络传输层角度进行分析,适用于绝大多数网络连接方式;但是需要开发人员熟练掌握网络传输、网络协议等基础知识,开发难度较大
    在Java语言中,提供了一组URL处理类,封装了Socket编程技术的实现细节,用来方便开发人员进行网络连接、网络数据传输等常用的网络任务
  • 直接使用URL类,可以方便地处理各种常见协议的网络连接
  • 使用URL类进行网络连接,相当于直接进行远程输入/输出流操作,只需开发人员熟练掌握常用IO操作即可,大大降低开发难度

URL网络编程核心操作类

1、URL类:统一资源定位符,指向互联网“资源”的指针
常用的构造方法:

  • URL(String url); // 通过给定字符串建立URL对象
    常用方法:
  • InputStream openStream(); // 打开当前URL连接的输入流
  • URLConnection openConnection(); // 建立URL网络连接
    2、URL代码:
URL myURL = new URL("http://java.sun.com");

String protocal = myURL.getProtocol();
String host = myURL.getHost();
String file = myURL.getFile();
int port = myURL.getPort();
String ref = myURL.getRef();

System.out.println(protocal + ", " + host + ", " + file + ", " + port + ", " + ref);

3、URLConnection类:应用程序和 URL 之间的通信链接,用于读取和写入此 URL 引用的资源
对象的建立方法:

  • 通过URL对象的openConnection()方法创建
  • 使用构造方法:URLConnection( URL url)
    常用方法:
  • 获得响应消息头类方法:getContentType()、getContentLength()、getContentEncoding()、……
  • 获得响应消息主体:getContent()
  • 获得当前连接输入/输出流对象:getInputStream()、getOutputStream()
url = new URL("http://");
// 打开连接
URLConnection conn = url.openConnection();
// 得到输入流
InputStream is = conn.getInputStream();
// 关于IO流的用法和写法一定要熟悉
OutputStream os = new FileOutputStream("d:\\baidu.png");

byte[] buffer = new byte[2048];
int length = 0;

while (-1 != (length = is.read(buffer, 0, buffer.length))) {
os.write(buffer, 0, length);
}
is.close();
os.close();

4、HttpURLConnection类:特定支持HTTP协议的URLConnection
对象建立方法:

  • 通过URL对象的openConnection()方法创建,强制转换为目标对象
  • 使用构造方法:HttpURLConnection( URL url)
    常用方法:
  • 从URLConnection类继承的方法
  • 针对HTTP请求响应消息的特定方法:getRequestMethod()、setRequestMethod()、getResponseCode()、getResponseMessage()、……

URL网络编程实例:文件下载

下载服务器端文件,基本思路:

  • 创建URL对象:URL url = new URL( 文件地址 )
  • 获取服务器端输入流:InputStream is = url.openStream()
String sUrl = "http://pic42.nipic.com/20140608/12504116_194242259000_2.jpg";
URL url = new URL(sUrl);	// 创建URL对象
InputStream in = url.openStream();	// 获得网络输入流
// 创建文件输出流
FileOutputStream out = new FileOutputStream(“cat.jpg");
int b;
while ((b = in.read()) != -1) {
	out.write(b);		// 写入文件
}
// 关闭输入输出流
out.close();    in.close();

URL网络编程实例:获取响应信息

获取服务器HTTP响应消息(消息头和消息主体)

  • 访问网址:http://software.hebtu.edu.cn/
  • 获取该网页的服务器字符编码、文档类型、服务器响应状态码、网页主体等
URL url = new URL(rootUrl);	//  创建Url对象
// 得到URLConnection连接对象
URLConnection conn = url.openConnection();
HttpURLConnection hc = (HttpURLConnection) conn;
// 获得响应消息头
conn.getContentType();
conn.getContentLength();
conn.getContentEncoding();
// 获得HTTP消息状态码
hc.getResponseCode();
hc.getResponseMessage();
// 获得HTTP响应消息主体
hc.getContent();

Socket网络编程简介

客户端和服务器端建立连接后,连接两端将会建立一个虚拟“线缆”,在网络编程中称之为Socket(套接字);其后在网络两端传输数据都是通过Socket进行的

  • Socket借助IP地址和端口号,对应某一台主机中的某一个应用程序
  • Socket的主要作用是维护网络连接、在网络双方传输数据

Socket网络编程核心操作类

Socket类:客户端套接字类。实现客户端向服务器发送数据、接收服务器数据等功能;实现服务器端向客户端发送数据、接收客户端数据等功能
构造方法

  • Socket(InetAddress address, int port);
  • Socket(String host, int port);
    常用方法:
  • getInputStream(); // 获得网络输入流
  • getOutputStream(); // 获得网络输出流
  • close(); // 关闭Socket连接
    **注意:**客户端与服务器端通信时,借助网络输入/输出流进行传输;但是对于客户端和服务器而言,输入流或输出流是相对的

客户端Socket应用程序

客户端Socket应用程序所做的工作主要有:
与服务器端建立连接(通过IP和端口号确定主机上的程序)

  • Socket client = new Socket(“localhost”, 80)
    向服务器端发送数据,接收服务器端数据
  • 向服务器端发送数据:os = client.getOutputStream()
  • 接收服务器端数据:is = client.getInputStream()
    关闭Socket连接
  • client.close()
Socket   client = new Socket("127.0.0.1", 8888);
// 获得网络输入/输出流
InputStream is = client.getInputStream(); // 获得网络输入流
OutputStream os = client.getOutputStream(); // 获得网络输出流
// 发送数据到server
String request = "this is a client request!";
os.write(request.getBytes());
os.flush();// 刷新请求
// 接收响应
byte[] b = new byte[1024];
StringBuffer strb = new StringBuffer();
while (is.read(b) != -1) {
strb.append(new String(b));
}
System.out.println(strb.toString());
// 关闭连接
is.close();
os.close();
client.close();

Socket网络编程核心操作类

ServerSocket类:服务器端套接字类。监听服务器指定端口,接收客户端连接请求
构造方法:

  • ServerSocket(int port)
    常用方法:
  • accept(); // 用于产生“阻塞”,直到接收一个连接,返回客户端Socket对象
  • close(); // 关闭服务器端Socket监听

服务器端Socket应用程序

服务器端所做的主要工作有:
监听特定端口

  • ServerSocket server = new ServerSocket(8888)
    接收客户端连接
  • Socket client = server.accept()
    接收客户端请求,向客户端发送响应
  • 接收客户端请求数据:is = client.getInputStream()
  • 向客户端响应数据:os = client.getOutputStream()
    关闭连接
  • 关闭客户端:client.close()
  • 关闭服务器端:server.close()
server = new ServerSocket(8888);
// 接收客户端连接
System.out.println("server listener");
Socket client = server.accept();
// 获得客户端请求
InputStream is = client.getInputStream();
byte[] b = new byte[1024];
is.read(b);
System.out.println("Server received:" + new String(b));

// 向客户端发送响应
OutputStream os = client.getOutputStream();
os.write(("this is server return string !").getBytes());
// 关闭网络连接
is.close();
os.close();
client.close();
server.close();

单Socket客户端和单服务器端一次通讯

  • ServerSocket建立后,通过accept来等待Client连接
  • Client连接Server端
  • Server端建立inputstream和outputstream
  • Client端建立inputstream和outputstream
  • 双方一次通讯
  • 各自关闭自己的inputstream和outputstream

单服务器端接收多次通讯

  • ServerSocket建立后,通过accept来等待Client连接
  • Client连接Server端
  • Server端建立inputstream和outputstream
  • Client端建立inputstream和outputstream
  • 双方一次通讯
  • Client关闭
  • Server端等待下次连接
    示例:建立服务器端程序,监听8888端口号,返回客户端多次请求数据。等待结束标记
server = new ServerSocket(8888);
while(true){
    // 接收客户端连接
    System.out.println("server listener");
    Socket client = server.accept();
    // 获得客户端请求
    InputStream is = client.getInputStream();
    byte[] b = new byte[1024];
    is.read(b);
    String result = new String(b);
    System.out.println("Server received:" + result);
// 向客户端发送响应
    OutputStream os = client.getOutputStream();
    os.write(("this is server return string !").getBytes());
    // 关闭网络连接
    is.close();
    os.close();
    client.close();
    if (result.startsWith("exit")) {
        break;
    }
}
server.close();

单服务器端多线程接收多次通讯

  • ServerSocket建立后,通过accept来等待Client连接
  • Client连接Server端
  • Server开启一个新的线程去处理
  • 在线程中,Server端建立inputstream和outputstream
  • Client端建立inputstream和outputstream
  • Client关闭
  • Server端等待下次连接
    示例:服务器端开启新的线程接收客户端请求
public class MyRunnable implements Runnable {
private Socket socket;

public MyRunnable(Socket socket) {
this.socket = socket;
}

public void run() {
           //处理接收请求返回数据….
}
}
package ReviewJavaIntnet;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientDemo1 {

	public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
		Socket socket=new Socket("127.0.0.2",8888);
		OutputStream oStream=socket.getOutputStream();
		String string="你好我是客户端1!!";
		oStream.write(string.getBytes());
		oStream.flush();
		
		System.out.println("发送完毕!");
		Thread.sleep(3000);
		InputStream iStream=socket.getInputStream();
		byte[] clientByte=new byte[2048];
		iStream.read(clientByte);
		System.out.println(new String(clientByte));
		
		
		oStream.close();
		iStream.close();
		socket.close();
	}
}

package ReviewJavaIntnet;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientDemo001 {

	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket=new Socket("127.0.0.2",8888);
		OutputStream oStream=socket.getOutputStream();
		String string="你好服务器,我是客户端二号";
		oStream.write(string.getBytes());
		oStream.flush();
		
		oStream.close();
		socket.close();
	}
}

package ReviewJavaIntnet;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

class serverThread extends Thread {
	private Socket socket;
	public serverThread(Socket socket) {
		this.socket=socket;//通过构造方法将socket传进来
	}
	
	public void run() {//重写run方法
		InputStream iStream;
		OutputStream oStream;
		System.out.println(this.getName());//打印当前进程的名字
		try {
			iStream=socket.getInputStream();//获得输入流
			byte[] clientByte=new byte[2048];
			iStream.read(clientByte);
			System.out.println(new String(clientByte));
			iStream.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
}

public class SeverDemo2 {

	public static void main(String[] args) throws IOException {
		ServerSocket serverSocket=new ServerSocket(8888);
		int i=0;
		while(true) {
			System.out.println("等待连接中........");
			Socket socket=serverSocket.accept();
			System.out.println("连接成功");
			if(i==5) {
				break;
			}
			Thread thread=new serverThread(socket);
			thread.start();
		}
		serverSocket.close();
	}
}

客户端端多线程接收网络响应

客户端程序示例:开辟新线程监听服务器端响应,主线程接收用户输入并向服务器发送请求

Socket client = new Socket("localhost", 8888);  // 建立网络连接
// 启动线程,读取服务器端响应消息
new HandleServerResponseMessage(client).start();
// 接收用户键盘输入,发送到服务器端
BufferedReader in = new BufferedReader(
		new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(client.getOutputStream());
String msg = null;
while ((msg = in.readLine()) != null) {
	out.println(msg);
	out.flush();
}

服务器端程序示例:

// 建立服务器端Socket
ServerSocket server = new ServerSocket(8888);
// 监听并处理客户端请求
while (true) {
// 接收客户端请求
Socket client = server.accept();
// 开启新的线程请求
new HandleClientRequestMessage(client).start();
}

UDP网络编程简介

建立网络连接时,有两种传输层协议(TCP传输协议和UDP传输协议)

  • UDP传输协议:一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务
    UDP传输协议通过数据包方式向服务器发送数据,那么在数据包中肯定需要包含服务器的IP信息、端口信息等内容。因此,UDP网络编程必须提供以下对象来完成不同的任务:
  • 网络两端接收消息或发送消息的对象(监听本机端口、发送消息、接收消息)
  • 数据包对象(包含目的地IP和端口信息、数据报文信息)

UDP网络编程核心类

DatagramSocket类:客户端/服务器端网络Socket端口对象
构造方法:

  • DatagramSocket(); // 创建一个空的Socket对象
  • DatagramSocket(int port); // 创建指定监听端口的Socket对象
    常用方法:
  • void send(DatagramPacket p); // 发送数据报文
  • void receive(DatagramPacket p); // 接收数据报文
    DatagramPacket类:数据报文对象
    构造方法:
  • DatagramPacket(byte[] buf, int len); // 用空数组创建对象,用来接收数据
  • DatagramPacket(byte[] buf, int offset, int len); // 接收数据的特定部分
  • DatagramPacket(byte[] buf, int len, InetAddress addr, int port); // 包含数据的数组创建对象,用来发送数据,同时指明数据目的地和目标端口号
  • DatagramPacket(byte[] buf, int offset, int len, InetAddress addr, int port); // 发送数据的指定部分

UDP网络编程实例

客户端程序:
基本工作流程:

  • 创建DatagramSocket对象
  • 封装请求数据,
  • 创建DatagramPacket对象
  • 发送请求
// 创建DatagramSocket对象
DatagramSocket client = new DatagramSocket();
// 准备请求数据
byte[] buf = “客户端请求数据".getBytes();
InetAddress address = InetAddress.getLocalHost();
// 创建DatagramPacket对象
DatagramPacket request = 
	new DatagramPacket(buf, buf.length, address , 8888);
// 发送请求
client.send(request);

服务器程序:
基本工作流程:

  • 创建DatagramSocket对象,监听特定端口
  • 创建DatagramPacket对象(空缓冲区)
  • 接收客户端请求
  • 封装服务器响应数据,创建DatagramPacket对象
  • 发送服务器响应给指定客户端
// 创建DatagramSocket对象,监听特定端口
DatagramSocket server = new DatagramSocket(8888);
// 准备空缓冲区
byte[] buf = new byte[1024];
// 循环等待客户端请求
while (true) {
	// 创建DatagramPacket对象
	DatagramPacket request = new DatagramPacket(buf, buf.length);
	// 接收客户端请求
	server.receive(request);
	// 准备服务器端响应数据包
	byte[] resBuf = "from server: ".getBytes();
	DatagramPacket response = new DatagramPacket(
		resBuf, resBuf.length, request.getAddress(), request.getPort());
	// 发送服务器响应
	server.send(response);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值