网络编程图解
java网络编程需要写两份代码:服务端代码和客户端代码
服务端与客户端通过Socket连接,两端之间通过字节流进行数据交互
socket是应用层与传输层中间的一个软件抽象层,它是一组接口。它把TCP/IP这些复杂的协议统一封装起来
对于我们只要知道如何使用socket就好,就已经符合了传输层往下的一大串协议
1.服务端
服务端使用ServerSocket类创建服务端
这个类实现了服务器套接字。 服务器套接字等待通过网络进入的请求。它根据该请求执行一些操作,然后可能将结果返回给请求者。
服务器套接字的实际工作由SocketImpl类的实例执行。 应用程序可以更改创建套接字实现的套接字工厂,以配置自己创建适合本地防火墙的套接字。
构造方法:
ServerSocket(int prot);//使用本机ip开启prot端口创建服务端
代码演示:
package com.qianfeng.cl;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* @Title DemoServer.java
* @Package com.qianfeng.cl
* @Description
* @author CL
* @date 2020年3月17日
* @version 1.0
*/
public class DemoServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream inputStream = null;
OutputStream outputStream = null;
BufferedWriter bw = null;
BufferedReader br = null;
try {
serverSocket = new ServerSocket(6666);//创建一个服务端
System.out.println("服务启动了.......");
//开启监听,并获取Socket
socket = serverSocket.accept();
//传输数据
outputStream = socket.getOutputStream();
//可转换成字符流输出
bw = new BufferedWriter(new OutputStreamWriter(outputStream));
//传输数据到客户端
String str = "hello "+socket.getInetAddress().getHostName()+" client\n";//一行数据
bw.write(str);//发送数据
bw.flush();//写入后需要刷新缓冲区
System.out.println("数据传输结束");
//读取数据
inputStream = socket.getInputStream();
//可转换成字符输入流
br = new BufferedReader(new InputStreamReader(inputStream));
System.out.println(br.readLine());//打印一行
System.out.println("服务器停止");
} catch (Exception e) {
e.printStackTrace();
}finally {//关闭
if(null != bw) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != br) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != socket) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != serverSocket) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
代码详解:
- 利用new ServerSocket();开启了一个端口为6666的服务端
- serverSocket.accept();开启服务端监听等待客户端连接(服务端将进入堵塞状态)
- 当客户端访问服务端时,serverSocket.accept()将访问一个Socket对象(服务端与客户端信息交互的通道)
- 服务端可以通过Socket对象获取OutputStream输出流对象(用于发送信息到客户端)
- 服务端可以通过Socket对象获取InputStream输入流对象(用于接收客户端发来的信息)
其中我们可以使用转换器将字节流转换成字符流
InputStreamReader(InputStream inputStream);//将字节输入流转换成字符输入流
OutputStreamWriter(OutputStream outputStream);//将字节输出流转换成字符输出流
注意:当使用字符流进行发送消息时,需要使用"\n"进行信息换行,写入后一定要flush();
2.客户端
客户端通过Socket访问服务端
该类实现客户端套接字(也称为“套接字”)。套接字是两台机器之间通讯的端点。
套接字的实际工作由SocketImpl类的实例执行。应用程序通过更改创建套接字实现的套接字工厂,可以配置自己创建适合本地防火墙的套接字。
构造方法:
Socket(String ip,int prot);//创建流套接字(即Socket对象)并将其连接到指定主机上的指定端口号。
代码演示:
package com.qianfeng.cl;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
/**
*
* @Title DemoClient.java
* @Package com.qianfeng.cl
* @Description
* @author CL
* @date 2020年3月17日
* @version 1.0
*/
public class DemoClient {
public static void main(String[] args) {
String ip = "localhost";
int prot = 6666;
Socket client = null;
InputStream inputStream = null;
OutputStream outputStream = null;
BufferedWriter bw = null;
BufferedReader br = null;
//获取Socket连接
try {
client = new Socket(ip,prot);
System.out.println("连接服务器成功");
//接收数据
inputStream = client.getInputStream();
//可转换成字符输入流
br = new BufferedReader(new InputStreamReader(inputStream));
System.out.println(br.readLine());//打印一行
//发送数据
outputStream = client.getOutputStream();
//可转换成字符输出流
bw = new BufferedWriter(new OutputStreamWriter(outputStream));
String st = "hello server\n";//一行数据
bw.write(st);//发送数据
bw.flush();
System.out.println("信息发送成功");
} catch (Exception e) {
e.printStackTrace();
} finally {//关闭流
if(null != bw) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != br) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != client) {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
代码详解:
- 使用Socket(ip,prot);创建了一个与服务端的Socket连接
- 通过Socket的getInputStream();获取字节输入流对象
- 可以通过InputStreamReader(InputStream inputStream);方法可以将字节流转换成字符输入流对象
- 通过字符输入流,可以读取服务端发送过来的信息
- 通过Socket的getOutputStream();获取字节输出流对象
- 可以通过OutputStreamWriter(OutputStream outputStream);将字节输出流转换成字符输出流对象
3.Socket常用方法
public InetAddress getInetAddress()返回套接字所连接的地址。
public InetAddress getLocalAddress();//获取套接字所绑定的本地地址。
public void bind(SocketAddress bindpoint);//将套接字绑定到本地地址。如果地址为null,则系统将接收临时端口和有效的本地地址来绑定套接字。
public InputStream getInputStream();//返回此套接字的输入流。
public OutputStream getOutputStream();//返回此套接字的输出流。