什么是网络编程?
在说网络编程之前要先知道什么是网络,网络是一种实现资源共享和数据传输的系统。而网络编程就是使用代码编写程序来进行网络之间数据的传输。使用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();
}
}
}