先上代码全文,整节课老师的代码全部包含在下方代码块中
注意: package 和 import 均不包含在代码块中,需要自行添加
tips:复制代码虽然方便,实践更重要
代码全文后有我个人还原的上课过程,仅供思路参考
* @author yangshiwei
* @Description 服务端
* 1:接收客户端请求
* 2:输出客户端发来的消息
* @date 2021/5/14-14:41
*/
public class MyServerSocket {
private int port;
private ServerSocket serverSocket;
public MyServerSocket(int port) {
this.port = port;
try {
this.serverSocket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
public void getRequest() {
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
try {
// 获取输入流,接受客户端传递的消息
inputStream = serverSocket.accept().getInputStream();
// 提高效率
inputStreamReader = new InputStreamReader(inputStream);
// 加入缓冲区
bufferedReader = new BufferedReader(inputStreamReader);
String clientInfo = null;
if ((clientInfo = bufferedReader.readLine()) != null) {
System.out.println("client request info is: " + clientInfo);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 服务端的资源必须关闭
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
inputStreamReader.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void sendResponse() throws Exception {
}
public static void main(String[] args) throws Exception {
System.out.println("客户端已启动");
new MyServerSocket(8080).getRequest();
}
}
/**
* @author yangshiwei
* @Description 客户端:
* 1:访问服务器端
* 2:发送一句话
* @date 2021/5/14-15:01
*/
public class MyClientSocket {
public void sendMsg(String address, int port) throws IOException {
Socket socket = null;
OutputStream outputStream = null;
OutputStreamWriter outputStreamWriter =null;
try {
// 1.绑定服务端端口
socket = new Socket(address, port);
// 2.向端口发送信息
outputStream = socket.getOutputStream();
outputStreamWriter = new OutputStreamWriter(outputStream);
// 3.将请求信息写入输出流
outputStreamWriter.write("this is client' request");
// 4.刷新缓存
outputStream.flush();
outputStreamWriter.close();
outputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (outputStreamWriter != null) {
outputStreamWriter.close();
}
if (outputStream != null) {
outputStream.close();
}
if (socket != null) {
socket.close();
}
}
}
public static void main(String[] args) {
try {
new MyClientSocket().sendMsg("127.0.0.1", 8080);
} catch (IOException e) {
e.printStackTrace();
}
}
}
蓝色字体为本节课主要知识点,红色字体属于之前已经学习过的知识点,非红色字体看不懂,应认为是我语言表达能力有问题
建立MyServerSocket和MyClientSocket类,利用IO流,通过ServerSocket,解决网络通信问题。其中,使用异常处理,解决程序运行中遇到的问题
MyServerSocket类中,先新建两个对象:port 端口号 ;serverSocket 连接。
一开始老师上课的时候建了三个对象,包括address IP地址,后来发现服务端构建serverSocket不需要传入IP地址,最后删掉了。
构造函数只需要传入port。
public MyServerSocket(int port) {
this.port = port;
try {
this.serverSocket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
MyServerSocket类中,有两个功能函数,分别是getRequest();用来获取客户端的信号;sendRespone();用于返回客户端信息,本节课由于时间原因,只实现了第一个函数。
getRequest() 函数,一共分为五个步骤
1:获取字节输入流,用于接受客户端传递的消息。
2:生成字符输入流,用于保存字节输入流的信息,提高效率。
3:将获取到的字符流,存入生成的缓冲区。
4:将缓冲区中的文字输出。
5:结束连接,关闭资源。
其中第五步非常重要,服务器端没有关闭资源的话会导致程序无法运行,我就因为只关闭了客户的资源,没有关闭服务器端的资源,研究半天,蒸无语。
主函数中建立连接传入的参数,端口号:8080,可以为各种端口号,只要保证服务器端和客户端的端口号一样,并且不要使用已经规定好的端口,具体可以复习一下计算机网络的端口相关知识。
MyClientSocket类中,只有一个sendMsg()函数,传入的是访问的Ip地址和端口号。
一共也是分为五个步骤
1:绑定服务器端口。
2:向端口发送信息。
3:将请求信息写入输出流
4:刷新缓存。
5:信息传输完成,关闭资源
主函数传入的ip地址可以是127.0.0.1,也可以写localhost。
Server端的另一个函数是返回客户端一个确认消息,因此Client端也要生成一个接受信息的IO流,我写了好久,运行起来都不太对劲,没办法把自己的代码给大家参考。
大家也可以在局域网的环境下试试,一个电脑开启Server端,一个电脑开启Client端,Ip地址输入服务端的ip地址,端口号相同,理论上应该可以接收到信息,但我还没试过,大家有空可以试试看,要注意需要在同一个网络下测试。
以上就是本节课的全部内容以及我的一些个人看法,祝大家周末快乐,本节课内容很多,我自己也还不太理解,等我完全理解之后也许会再写一篇。