javaweb基础入门——Socket

1.1 了解javaweb

javaweb是写网站的, 网站开发是趋势

javaweb是spring必经之路

1.2 计算机网络基础

用网线和路由,光猫把不同计算机连起来,组成计算机网络系统

电脑有自己的ip地址,同一个网络中通过对方ip来ping他

电脑上的程序通过网络访问其他计算机,程序有自己的端口号

端口:0~65535

ip分为ipv4:四组数字,32bit,ipv6:128bit,现在正在向ipv6过渡

传输层协议:TCP,UDP

TCP:三次握手,四次挥手,保证两台计算机通信可靠

UDP:直接发送,不可靠,简单高效

1.3 Socket 技术

套接字,计算机通信的一种方式,操作系统底层一项通信技术,支持TCP和UDP,Java对Socket完美封装,非常好实现

实现:

服务端

public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(8080);// 服务端端口 8080
System.out.println("正在等待客户端->服务端");
Socket socket = server.accept();//没有客户端连接,线程阻塞,直到有客户端连接为止
System.out.println("客户端连接,IP地址为: "+socket.getInetAddress().getHostAddress());
}

客户端

public static void main(String[] args) throws Exception{
Socket socket = new Socket("localhost", 8080);
System.out.println("已连接到服务端");
}

先启动服务端,在启动客户端

image-20220515201729854

让服务端循环接受IP地址

public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(8080);// 服务端端口 8080
System.out.println("正在等待客户端->服务端");
while (true){
Socket socket = server.accept();//没有客户端连接,线程阻塞,直到有客户端连接为止
System.out.println("客户端连接,IP地址为: "+socket.getInetAddress().getHostAddress());
}
}

image-20220515211403170

实现多次连接服务端

1.4 用Socket传输数据

用IO流传输网络数据

客户端

public static void main(String[] args) throws Exception{
Socket socket = new Socket("localhost", 8081);
Scanner scanner = new Scanner(System.in);
System.out.println("已连接到服务器");
OutputStream stream = socket.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(stream);//转换流快速写入内容
System.out.println("请输入要发送到服务端的内容:");
String text = scanner.nextLine();
writer.write(text + '\n');//对方是readline()加换行符
writer.flush();
System.out.println("数据已发送" + text);
}

服务端

public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(8081);
System.out.println("等待客户端连接……");
Socket socket = server.accept();
System.out.println("客户端已连接,IP地址为:" + socket.getInetAddress().getHostAddress());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("接收到客户端数据:");
System.out.println(reader.readLine());
socket.close();
}

输出

image-20220515212544179

image-20220515212552630

同理服务端也可以接收客户端消息

客户端

public static void main(String[] args) throws Exception{
try (Socket socket = new Socket("localhost", 8080);
Scanner scanner = new Scanner(System.in)){
System.out.println("已连接到服务端!");
OutputStream stream = socket.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(stream); //通过转换流来帮助我们快速写入内容
System.out.println("请输入要发送给服务端的内容:");
String text = scanner.nextLine();
writer.write(text+'\n'); //因为对方是readLine()这里加个换行符
writer.flush();
System.out.println("数据已发送:"+text);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("收到服务器返回:"+reader.readLine());
}catch (IOException e){
System.out.println("服务端连接失败!");
e.printStackTrace();
}finally {
System.out.println("客户端断开连接!");
}
}

服务端

public static void main(String[] args) throws Exception{
try(ServerSocket server = new ServerSocket(8080)){ //将服务端创建在端口8080上
System.out.println("正在等待客户端连接...");
Socket socket = server.accept();
System.out.println("客户端已连接,IP地址为:"+socket.getInetAddress().getHostAddress());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); //通过
System.out.print("接收到客户端数据:");
System.out.println(reader.readLine());
OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
writer.write("已收到!");
writer.flush();
socket.close();
}catch (IOException e){
e.printStackTrace();
}
}

image-20220515221021956

image-20220515221030064

手动关闭单向的流

socket.shutdownOutput(); //关闭输出方向的流
socket.shutdownInput(); //关闭输入方向的流

image-20220515232703211

服务器不可能一直等客户端,可以设置一个时间

scoket.setSoTimeout(3000);

image-20220515232941922

手动连接服务端,在我们想要的时候再连接

try(Socket socket = new Socket();
Scanner scanner = new Scanner(System.in){
socket.connect(new InetSocketAddress("localhost",8080),1000)
//手动调用connect方法进行连接

image-20220515234045338

双方由于某种原因连接不到,一方始终持有连接,占用资源,这是我们不想看到的,用setKeepAlive方法解决

socket.setKeepAlive(true);

image-20220515234603130

TCP传输过程中会有一个缓冲区用于数据发送和接收,调节缓冲区大小优化效率

socket.setReceiveBufferSize(25565); //TCP接收缓冲区
socket.setSendBufferSize(25565); //TCP发送缓冲区

1.5 用Socket传输文件

Socket提供IO流,轻松实现文件传输

客户端

public static void main(String[] args) throws Exception{
try (Socket socket = new Socket("localhost",8080);){
FileInputStream fileInputStream = new FileInputStream("a.txt");
OutputStream stream = socket.getOutputStream();
byte[] bytes = new byte[1024];
int i;
while ((i = fileInputStream.read(bytes)) != -1){
stream.write(bytes,0,i);
}
fileInputStream.close();
stream.flush();
}catch (IOException e){
System.out.println("服务端连接失败!");
e.printStackTrace();
}
}

服务端

public static void main(String[] args) throws Exception{
try(ServerSocket server = new ServerSocket(8080)){ //将服务端创建在端口8080上
Socket socket = server.accept();
InputStream stream = socket.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream("net/data.txt");
byte[] bytes = new byte[1024];
int i;
while ((i = stream.read(bytes)) != -1){
fileOutputStream.write(bytes,0,i);
}
fileOutputStream.flush();
fileOutputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}

image-20220516001412976

1.6 用浏览器访问Socket服务器

服务端

public static void main(String[] args) throws Exception{
try(ServerSocket server = new ServerSocket(8080)){ //将服务端创建在端口8080上
System.out.println("正在等待客户端连接……");
Socket socket = server.accept();
System.out.println("客户端已连接,IP地址为:" + socket.getInetAddress().getHostAddress());
InputStream in = socket.getInputStream();
System.out.println("接收到客户端数据:");
while (true){
int i = in.read();
if (i == -1)break;
System.out.print((char) i);
}
}catch (IOException e){
e.printStackTrace();
}
}

浏览器端

image-20220516101220030

响应

image-20220516101303217

自定义响应内容

try(ServerSocket server = new ServerSocket(8080)){ //将服务端创建在端口8080上
System.out.println("正在等待客户端连接...");
Socket socket = server.accept();
System.out.println("客户端已连接,IP地址为:"+socket.getInetAddress().getHostAddress());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); //通过
System.out.println("接收到客户端数据:");
while (reader.ready()) System.out.println(reader.readLine()); //ready是判断当前流中是否还有可读内容
OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
writer.write("HTTP/1.1 200 Accepted\r\n"); //200是响应码,Http协议规定200为接受请求,400为错误的请求,404为找不到此资源(不止这些,还有很多)
writer.write("\r\n"); //在请求头写完之后还要进行一次换行,然后写入我们的响应实体(会在浏览器上展示的内容)
writer.write("lbwnb!");
writer.flush();
}catch (IOException e){
e.printStackTrace();
}

打开浏览器访问8080,不能显示,关防火墙也不行,知道原理就行了吧

posted @   鱼子酱caviar  阅读(332)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示