网络编程
一、网络编程中有两个主要的问题
- 如何准确地定位网络上一台或多台主机;定位主机上的特定的应用
- 找到主机后如何可靠高效地进行数据传输
二、网络编程中的两个要素
- 对应问题一:IP和端口号
- 对应问题二:提供网络通信协议:TCP/IP参考模型(应用层、传输层、网络层、物理+数据链路层)
三、通信要素一:IP和端口号
-
IP:唯一的标识 Internet 上的计算机(通信实体)
-
在Java中使用 InetAddress类 代表IP
-
IP分类:IPv4 和 IPv6 ; 万维网 和 局域网
-
域名:www.baidu.com
-
本地回路地址:127.0.0.1 对应着:localhost
-
如何实例化InetAddress:
两个方法:getByName(String host) 、 getLocalHost()
两个常用方法:getHostName() 、 getHostAddress()
-
端口号:标识正在计算机上运行的进程
要求:不同的进程有不同的端口号
范围:被规定为一个16位的整数 0~65535
-
端口号与IP地址的组合得出一个网络套接字:Socket
实现TCP的网络编程(1)
例子1:客户端发送信息给服务端,服务端将数据显示在控制台上
服务端
// 服务端
@Test
public void server() {
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
// 1.创建服务端的ServerSocket,指明自己的端口号
ss = new ServerSocket(8899);
// 2.调用accept()表示接受来自于客户端的socket
socket = ss.accept();
// 3.获取输入流
is = socket.getInputStream();
// 不建议这样写,可能会有乱码
// byte[] buffer = new byte[5];
// int len;
// while((len = is.read(buffer)) != -1) {
// String str = new String(buffer,0,len);
// System.out.print(str);
// }
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[5];
int len;
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
System.out.println(baos.toString());
System.out.println("收到来自:" + socket.getInetAddress().getHostName() + "的消息");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (baos != null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端
// 服务端
@Test
public void server() {
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
// 1.创建服务端的ServerSocket,指明自己的端口号
ss = new ServerSocket(8899);
// 2.调用accept()表示接受来自于客户端的socket
socket = ss.accept();
// 3.获取输入流
is = socket.getInputStream();
// 不建议这样写,可能会有乱码
// byte[] buffer = new byte[5];
// int len;
// while((len = is.read(buffer)) != -1) {
// String str = new String(buffer,0,len);
// System.out.print(str);
// }
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[5];
int len;
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
System.out.println(baos.toString());
System.out.println("收到来自:" + socket.getInetAddress().getHostName() + "的消息");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (baos != null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端
// 客户端
@Test
public void customer() {
Socket socket = null;
OutputStream os = null;
try {
// 1.创建 Socket 对象,指明服务器端的IP和端口号
InetAddress inet = InetAddress.getByName("127.0.0.1");
socket = new Socket(inet, 8899);
// 2.获取一个输出流,用于输出数据
os = socket.getOutputStream();
// 3.写出数据的操作
os.write("我是客户端".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4.资源的关闭
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
实现TCP的网络编程(2)
例题2:客户端发送文件给服务端,服务端将文件保存到本地
客户端
这里涉及到的异常,应该使用 try-catch-finally 处理
@Test
public void customer() throws IOException {
Socket socket = new Socket("127.0.0.1",9090);
OutputStream os = socket.getOutputStream();
FileInputStream fos = new FileInputStream("departments.png");
byte[] buffer = new byte[1024];
int len;
while((len = fos.read(buffer)) != -1) {
os.write(buffer,0,len);
}
fos.close();
os.close();
socket.close();
}
服务端
这里涉及到的异常,应该使用 try-catch-finally 处理
@Test
public void server() throws IOException {
ServerSocket ss = new ServerSocket(9090);
Socket socket = ss.accept();
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream("departmentsCopy.png");
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1) {
fos.write(buffer,0,len);
}
System.out.println("下载完成");
fos.close();
is.close();
socket.close();
ss.close();
}
实现TCP的网络编程(3)
例题3:从客户端发送文件给服务端,服务端保存到本地。并返回”发送成功“给客户端,并关闭相应的连接。
客户端
@Test
public void customer() throws IOException {
Socket socket = new Socket("127.0.0.1",8899);
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream("departments.png");
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer)) != -1) {
os.write(buffer,0,len);
}
// 关闭数据的输出
socket.shutdownOutput();
InputStream is = socket.getInputStream();
byte[] buffer1 = new byte[1024];
int len1;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while((len1 = is.read(buffer1)) != -1) {
baos.write(buffer1,0,len1);
}
System.out.println(baos.toString());
is.close();
fis.close();
os.close();
socket.close();
}
服务端
@Test
public void server() throws IOException {
ServerSocket ss = new ServerSocket(8899);
Socket socket = ss.accept();
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream("departmentsCopyBack.png");
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1) {
fos.write(buffer,0,len);
}
System.out.println("下载完成");
OutputStream os = socket.getOutputStream();
os.write("图片已下载完成".getBytes());
os.close();
fos.close();
is.close();
socket.close();
ss.close();
}