java中socket包边界结束标记,《JAVA学习笔记》---网络编程Socket篇

本文深入介绍了Java中的Socket编程,包括Socket的基本概念、工作原理以及客户端和服务器端的通信流程。通过示例展示了如何实现一对一和一对多的Socket通信,并提供了文件传输的示例。Socket作为TCP/IP协议的接口,简化了网络编程,允许在不同主机间建立逻辑连接。文章还提及了Socket编程中的输入输出流操作和资源管理。
摘要由CSDN通过智能技术生成

一.Socket概述

在JAVA的网络编程中主要涉及到的内容就是Socket编程。而Socket也称为套接字,是两台主机之间逻辑链接的端点。值得一提的是:Socket通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含了进行网络通信所必备的五种信息:连接使用的协议、本地主机的IP地址、本地进程的协议端口、远程主机的IP地址、远程进程的协议端口。

Socket,实际上是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。实际上,Socket跟TCP/IP协议没有必然的关系,Socket编程接口在设计的时候,就希望也能适应其他的网络协议。所以说,Socket的出现,只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,从而形成了我们知道的一些最基本的函数接口,比如create、listen、accept、send、read和write等等。

二.Socket整体流程

Socket编程主要涉及到客户端和服务器端两个方面,首先是在服务器端创建一个服务器套接字(ServerSocket),并把它附加到一个端口上,服务器端从这个端口监听连接。端口号的范围是0到65536,但是0到1024是为特权服务保留的端口号,我们可以选择任意一个当前没有被其他进程使用的端口。

客户端请求与服务器端进行连接的时候,根据服务器的域名或者IP地址,加上端口号,打开一个套接字。当服务器接受连接后,服务器端和客户端之间的通信就像输入输出流一样进行操作。

e70e867940e5ad4affb668248db02348.png

三.实例

一对一相互通信

服务器端

package study_demo1;

import java.io.*;

import java.net.ServerSocket;

import java.net.Socket;

public class ServerDemo {

public static void main(String[] args) throws IOException {

//1.创建Socket对象

ServerSocket ss = new ServerSocket(20000);

//2.等待客户端链接

Socket accept = ss.accept();

//3.获得输入流对象

InputStream is = accept.getInputStream();

int b;

while ((b = is.read()) !=-1){

System.out.print((char)b);

}

//4.获取输出流对象,开始写数据

/*涉及到中文需要用字符流

OutputStream os = accept.getOutputStream();

os.write("你谁啊?".getBytes());

*/

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));

bw.write("你谁啊?");

bw.newLine();

bw.flush();

//5.释放资源

// os.close();

is.close();

ss.close();

}

}

客户端

package study_demo1;

import java.io.*;

import java.net.Socket;

public class ClientDemo {

public static void main(String[] args) throws IOException {

//1.创建一个Socket对象

Socket socket = new Socket("127.0.0.1",20000);

//2.获取一个IO流开始写数据

OutputStream os = socket.getOutputStream();

os.write("hello".getBytes());

socket.shutdownOutput();//仅仅关闭输出流,并写一个结束标记,对socket没有任何影响

/*

涉及到中文需要用字符流,而不是字节流

//3.获得输入流对象

InputStream is = socket.getInputStream();

int b;

while ((b=is.read())!=-1){

System.out.print((char)b);

}*/

//把得到的字节流转换为字符流

BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

String line;

while ((line = br.readLine())!=null){

System.out.println(line);

}

//4.释放资源

// System.out.print("over?");

//is.close();

br.close();

os.close();

socket.close();

}

}

复制代码

一对多相互通信

服务器端

public class SocketServerM {

public static void main(String[] args) throws IOException {

int port = 7000;

int clientNo = 1;

ServerSocket serverSocket = new ServerSocket(port);

// 创建线程池

ExecutorService exec = Executors.newCachedThreadPool();

try {

while (true) {

Socket socket = serverSocket.accept();

exec.execute(new SingleServer(socket, clientNo));

clientNo++;

}

} finally {

serverSocket.close();

}

}

}

class SingleServer implements Runnable {

private Socket socket;

private int clientNo;

public SingleServer(Socket socket, int clientNo) {

this.socket = socket;

this.clientNo = clientNo;

}

@Override

public void run() {

try {

DataInputStream dis = new DataInputStream(

new BufferedInputStream(socket.getInputStream()));

DataOutputStream dos = new DataOutputStream(

new BufferedOutputStream(socket.getOutputStream()));

do {

double length = dis.readDouble();

System.out.println("从客户端" + clientNo + "接收到的边长数据为:" + length);

double result = length * length;

dos.writeDouble(result);

dos.flush();

} while (dis.readInt() != 0);

} catch (IOException e) {

e.printStackTrace();

} finally {

System.out.println("与客户端" + clientNo + "通信结束");

try {

socket.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

客户端同上

复制代码

写入文件通信

服务器端

package study_demo_Inter;

import java.io.*;

import java.net.ServerSocket;

import java.net.Socket;

public class Server {

public static void main(String[] args) throws IOException {

ServerSocket ss = new ServerSocket(10610);

Socket accept = ss.accept();

//网络中的流,从客户端读取数据

BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());

//本地的IO流,把数据写到本地中,实习永久化存储

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Exp1_CaiYQ\\ServerDir\\copy.png"));

int b;

while ((b=bis.read())!=-1){

bos.write(b);

}

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));

bw.write("上传成功");

bw.newLine();

bw.flush();

bos.close();

accept.close();

ss.close();

}

}

客户端

package study_demo_Inter;

import java.io.*;

import java.net.ServerSocket;

import java.net.Socket;

public class Server {

public static void main(String[] args) throws IOException {

ServerSocket ss = new ServerSocket(10610);

Socket accept = ss.accept();

//网络中的流,从客户端读取数据

BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());

//本地的IO流,把数据写到本地中,实习永久化存储

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Exp1_CaiYQ\\ServerDir\\copy.png"));

int b;

while ((b=bis.read())!=-1){

bos.write(b);

}

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));

bw.write("上传成功");

bw.newLine();

bw.flush();

bos.close();

accept.close();

ss.close();

}

}

复制代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值