什么是网络编程?
在说网络编程之前要先知道什么是网络,网络是一种实现资源共享和数据传输的系统。而网络编程就是使用代码编写程序来进行网络之间数据的传输。使用java进行网络之间数据的传输是比较简单的,java中提供了一些现成的类供我们使用,其实这一块也没什么好理解的,记住就可以了,这里只是简单介绍一下网络之间进行数据传输的方式和如何使用java中提供类进行编程。
如何进行数据的传输?
假如有两台机器服务器A和客户端B需要进行数据传输,首先,想到的问题应该是如何确定这两台机器。在网络中每一个机器都使用一个ip地址作为自己的唯一标识,所以首先应该确认机器的ip地址,接着,客户端B将信息发送到了服务器A,这是服务器中的哪个应用去接收处理客户端发来的信息呢?每一台机器中有65535个端口, 每一个端口对应着一个应用程序,所以还要指定端口(port)来告诉服务器将信息发送到哪个应用中进行处理。
这里可能有一个疑问,数据是如何由客户端发送到服务器的呢?
数据在传输时需要遵循特定的协议,这里有两个协议可供选择: TCP协议提供面向连接的服务,使用字节流的方式进行传输,是有序、可靠传输。 UDP协议提供无连接的服务,使用数据包的方式进行传输,是不可靠的传输。
java如何实现数据传输?
接下来介绍一下java中的网编实现方式,在java中使用socket套接字来逻辑表示网络中的结点(客户端B和服务器A),套接字的两个基本属性就是ip和端口。数据进行传输时先通过套接字来连接两个结点,然后使用套接字中提供的数据流来进行数据的传输,等到传输结束后,则注销两个套接字,结束结点之间的通信。
针对不同协议的数据传输,java中提供了不同的实现方式,使用TCP协议进行java进行网络编程时,由于需要先创建连接,所以必须先开发服务器端,当服务器端没有开启时,客户端访问会报错,看一下根据TCP协议进行数据传输的例子,代码如下:
/*** 服务器端**/
public class SocketServer {public static void main(String[] args) {//1.声明套接字和一系列的流对象ServerSocket serverSocket = null;Socket socket = null;InputStream inputStream = null;OutputStream outputStream = null;try {// 2.构造套接字serverSocket = new ServerSocket(9002);// 3.使服务器处于阻塞状态,确定可以通信,获取套接字,等待客户端发送信息socket = serverSocket.accept();// 4.获取流对象,读取流中的信息inputStream = socket.getInputStream();byte []bs = new byte[2048];inputStream.read(bs);System.out.println("接收到客户端的信息:"+new String(bs,"utf-8"));// 5、禁用套接字中的输入流socket.shutdownInput();// 6. 反馈信息,往流中写入数据,供客户端获取outputStream = socket.getOutputStream();outputStream.write("我是服务器端".getBytes());socket.shutdownOutput();} catch (IOException e) {e.printStackTrace();} finally {try {if (inputStream != null) {inputStream.close();}if (outputStream != null) {outputStream.close();}socket.close();} catch (IOException e) {e.printStackTrace();}}}
}------------------------------------------------------------------/*** 客户端**/
public class SocketClient {public static void main(String[] args) {// 1.创建客户端套接字和用于获取数据流对象Socket socket = null;InputStream in = null;OutputStream out = null;try {// 2.构造套接字,用于连接服务器端socket = new Socket("127.0.0.1", 9002);// 3.创建与服务器之间的数据连接流,往服务器端发送数据out = socket.getOutputStream();String message = "我是客户端";out.write(message.getBytes());socket.shutdownOutput();// 4.获取与服务器之间的数据连接流,获取到服务器返回的信息byte []b = new byte[2048];in = socket.getInputStream();in.read(b);System.out.println("接收到服务端的信息:"+new String(b,"utf-8"));socket.shutdownInput();} catch (Exception e) {// TODO: handle exception} finally {try {if (in != null) {in.close();}if (out != null) {out.close();}socket.close();} catch (IOException e) {e.printStackTrace();}}}
}
上边这是一个服务器对应要给客户端,当多个客户端访问一台服务器时,使用多线程即可,每来一个客户端就创建一个新线程,创建一个新的套接字。
当使用UDP协议进行java开发时,服务器端不需要一定开启,客户端发送信息,不会管服务器是否接受成功了,看一下使用UDP协议进行数据传输的例子,代码如下:
/*** 服务器端 */
public class Recive {public static void main(String[] args) {// 1.创建数据报包套接字DatagramSocket socket = null;// 2.创建数据包DatagramPacket dpGet = null;DatagramPacket dpSend = null;try {// 3.构造一个数据包byte[] b = new byte[2048];dpGet = new DatagramPacket(b, b.length);// 4.构造套接字,并开启服务器,等待接受数据包socket = new DatagramSocket(9002);socket.receive(dpGet);//服务器阻塞,等待访问System.out.println("接受到客户端的信息:"+new String(b));// 5.从包中获取到客户端的套接字地址信息,并返回客户端信息SocketAddress socketAddress = dpGet.getSocketAddress();byte[] sendData = "这是服务器返回的信息".getBytes();dpSend = new DatagramPacket(sendData, sendData.length, socketAddress);socket.send(dpSend);} catch (SocketException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {socket.close();}}
}-----------------------------------------------------/*** 客户端 */
public class Send {public static void main(String[] args) {// 1.声明数据报包套接字DatagramSocket socket = null;// 2.声明数据库报包DatagramPacket dp = null;try {// 4.构建套接字socket = new DatagramSocket();// 5.构建发送包byte[] bytes = "客户端发送的信息".getBytes();dp = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("localhost"), 9002);// 6.发送数据报包socket.send(dp);} catch (UnknownHostException e) {e.printStackTrace();} catch (SocketException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {// 释放资源socket.close();}}
}