Socket(套接字)封装了TCP协议的通讯细节,使得我们使用它可以与服务器建立网络连接,并通过它获取两个流(一个输入一个输出),然后使用这两个流的读写操作完成与远端计算机的数据交互工作
ServerSocket运行在服务端,作用有两个:
1:向系统申请服务端口,客户的Socket就是通过这个端口与服务端建立连接的
2:监听服务端口,一旦一个客户端通过该端口建立连接则会自动创建一个Socket,并通过该Socket与客户端进行数据交互
如果我们吧Socket比喻为电话,那么ServerSocket相当于某客服中心的总机。
/*
实例化Socket时要传入两个参数
参数1:服务端的地址信息,可以是IP地址,如果链接本机可以写成"localhost"
参数2:服务端开启的服务端口
我们通过IP找到网络上的服务端计算机,通过端口连接运行在该机器上的服务端应用程序
实例化的过程就是链接完成的过程,如果链接失败会抛出异常:
java.net.ConnecException:Connection refused:connect
*/
public class Client {
private Socket socket;
public Client() {
try {
System.out.println("正在连接服务器...");
socket=new Socket("localhost",8088);
System.out.println("与服务器连接成功");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 客户端开始工作的方法
*/
public void start(){
}
public static void main(String[] args) {
Client client=new Client();
}
}
/*
ServerSocket提供了接受客户端链接的方法:
Socket accept()
这个方法是一个阻塞方法,调用后方法"卡住",此时开始等待客户端的链接,直到一个客户端链接,
此时该方法会立即返回一个Socket实例
通过这个Socket实例就可以与客户端进行交互了
可以理解为此操作是接电话,电话没响就一直等
*/
public class Server {
private ServerSocket serverSocket;
public Server() {
try {
System.out.println("正在启动服务器");
serverSocket=new ServerSocket(8088);
System.out.println("服务器启动完毕");
} catch (IOException e) {
e.printStackTrace();
}
}
public void start(){
System.out.println("等待客户端连接...");
try {
Socket accept = serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("一个客户端连接");
}
public static void main(String[] args) {
Server server=new Server();
server.start();
}
}
Socket提供了两个重要的方法
//客户端
public class Client {
private Socket socket;
public Client() {
try {
System.out.println("正在连接服务器...");
socket=new Socket("localhost",8088);
System.out.println("与服务器连接成功");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 客户端开始工作的方法
*/
public void start(){
try {
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os);
BufferedWriter bw=new BufferedWriter(osw);
PrintWriter pw=new PrintWriter(bw,true);
pw.println("天青色等烟雨");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client=new Client();
client.start();
}
}
//服务端
public class Server {
private ServerSocket serverSocket;
public Server() {
try {
System.out.println("正在启动服务器");
serverSocket=new ServerSocket(8088);
System.out.println("服务器启动完毕");
} catch (IOException e) {
e.printStackTrace();
}
}
public void start(){
try {
System.out.println("等待客户端连接...");
Socket socket = serverSocket.accept();
System.out.println("一个客户端连接");
InputStream is = socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
String line = br.readLine();
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server=new Server();
server.start();
}
}
缓冲字符输出流
缓冲字符输出流需要记住的是PrintWriter和BufferedReader
作用:
1.块写或块读文本数据加速
2.可以按行写或读取串
java.io.PrintWriter具有自动行刷新的缓冲字符输出流
常用构造
PrintWriter(String filename):可以直接对给定路径的文件进行写操作
PrintWriter(File file):可以直接对File表示的文件进行写操作
上述两种构造器内部会自动完成流连接操作
PrintWriter(OutputStream out):将PW链接在给定的字节流上(构造方法内部会自行完成转换流等流连接)
PrintWriter(Writer writer):将PW链接在其他字符流上
PrintWriter(OutputStream out,boolean autoflush)
PrintWriter(Writer writer,boolean autoflush)
上述两个构造器可以在链接到流上的同时传入第二个参数,如果该值为true则开启了自动刷新功能
常用方法
void println(String line):按行写出一行字符串
特点
自动行刷新,当打开了该功能后,每当使用println方法写出一行后就会自动flush一次