一.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地址,加上端口号,打开一个套接字。当服务器接受连接后,服务器端和客户端之间的通信就像输入输出流一样进行操作。
三.实例
一对一相互通信
服务器端
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();
}
}
复制代码