1.概念:
套接字(socket)是一种通信机制,凭借这种机制,客户/服务器系统的开发工作既可以在本地单机上进行,也可以跨网络进行。Linux所提供的功能(如打印服务、连接数据库和提供Web页面)和网络工具(如用于远程登录的rlogin和用于文件传输的ftp)通常都是通过套接字来进行通信的。
套接字的创建和使用与管道是有区别的,因为套接字明确地将客户和服务器区分开来。套接字机制可以实现将多个客户连接到一个服务器,
2.TCP、UDP通信编程模型
3.Java中的Socket
3.1 Socket类和ServerSocket类方法介绍
1.Socket类
public Socket accept() : 创建套接字对象并将其连接到指定主机上的指定端口号。如果指定的host是null ,则相当于指定地址为回送地址。
public InputStream getInputStream() : 返回此套接字的输入流。
public OutputStream getOutputStream() : 返回此套接字的输出流。
public void close() : 关闭此套接字
2.ServerSocket类
public ServerSocket(int port) :使用该构造方法在创建ServerSocket对象时,就可以将其绑定到一个指定的端口号上,参数port就是端口号。
public Socket accept() :侦听并接受连接,返回一个新的Socket对象,用于和客户端实现通信。该方法会一直阻塞直到建立连接。
3.2 简单案例
我们这边直接用一个使用TCP协议的简单案例来演示一下Java中Socket类的使用,此案例是使用Scanner类,使我们在控制台实现键盘录入,实现一个简单的聊天室的案例
客户端代码:
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static final Logger LOGGER = LoggerFactory.getLogger(com.itheima.a04_tcp_2.Client.class);
public static void main(String[] args) throws IOException {
Socket socket = null;
BufferedWriter bw = null;
try {
//1.创建Socket对象,并同时请求与服务端程序的连接
socket = new Socket("127.0.0.1", 9527);
//2.从Socket通信管道中得到一个字节输出流,用来发数据给服务端程序
OutputStream os = socket.getOutputStream();
//3.转换流,转为write,方便处理文本
OutputStreamWriter osw = new OutputStreamWriter(os);
//4.缓冲流
bw = new BufferedWriter(osw);
//也可以这样写
//bw = new BufferedWriter(new OutputStreamWriter(new Socket("127.0.0.1", 9527).getOutputStream()));
//写入数据
while (true) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
//晚安触发退出命令
if ("晚安".equals(s)) {
System.out.println("程序退出");
break;
}
bw.write(s);
bw.newLine();
bw.flush();
}
} catch (IOException e) {
LOGGER.error("程序异常",e);
} finally {
IOUtils.closeQuietly(bw, socket);
}
}
}
服务端代码:
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static final Logger LOGGER = LoggerFactory.getLogger(com.itheima.a04_tcp_2.Server.class);
public static void main(String[] args) throws IOException {
Socket socket = null;
BufferedReader br = null;
try {
//1.创建ServerSocket对象,同时为服务端注册端口
ServerSocket serverSocket = new ServerSocket(9527);
//2.使用ServerSocket对象,调用一个accept方法,等待客户端的连接请求
socket = serverSocket.accept();
//3.从socket通信管道中得到一个字节输入流
InputStream is = socket.getInputStream();
//4.转换流,转为Reader,方便处理文本
InputStreamReader reader = new InputStreamReader(is);
//5.缓冲流,提高效率
br = new BufferedReader(reader);
//链式编程写法
//br = new BufferedReader(new InputStreamReader(new ServerSocket(9527).accept().getInputStream()));
//读取数据
while (true) {
String s = br.readLine();
if ("晚安".equals(s)) {
break;
}
System.out.println(s);
}
} catch (IOException e) {
LOGGER.error("程序异常",e);
} finally {
//关闭连接
IOUtils.closeQuietly(br, socket);
}
}
}
效果演示:
客户端控制台输入:
服务端控制台展示: