所谓socket
通常也称作”套接字“,用于描述IP
地址和端口,是一个通信链的句柄。应用程序通常通过”套接字”向网络发出请求或者应答网络请求。
InetAddress
InetAddress
可以获取对应ip
或者对应域名的相关信息,例如ip
信息和域名信息
只说一下用的比较多的吧
获取InetAddress
对象,只能使用工厂构造方法获取。
1 2 3 4 5 6 7
| InetAddress localHost = InetAddress.getLocalHost(); InetAddress localhost = InetAddress.getByName("localhost");
InetAddress inetAddress = InetAddress.getByName("DESKTOP-GQI06FR");
InetAddress inetAddress = InetAddress.getByName("www.baidu.com");
|
InetAddress
对象的使用,常用方法
1 2 3 4
| String hostAddress = localHost.getHostAddress();
String hostName = localHost.getHostName();
|
TCP客户端
以发送简单的字符串为例。
TCP发送数据的步骤
- 创建客户端的Socket对象(Socket)
- 获取输出流,写数据
- 释放资源
首先创建Socket对象
1
| Socket socket = new Socket("127.0.0.1",50000);
|
常用的构造方法有两个:
Socket (InetAddress address, int port)
创建流套接字并将其连接到指定IP
地址的指定端口号
Socket (String host, int port)
创建流套接字并将其连接到指定主机上的指定端口号
获取字节输出流
你可以使用普通的输出流
1
| OutputStream outputStream = socket.getOutputStream();
|
你还可以使用字符缓存流
1
| BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
|
还可以使用字节缓存流
1
| BufferedOutputStream outputStream = new BufferedOutputStream(socket.getOutputStream());
|
获取字节输入流
获取输入流可以获取反馈信息。
1
| InputStream clientInputStream = socket.getInputStream();
|
字符缓存流和字节缓冲流和上面的类似。
写数据
1 2 3 4
| Scanner sc = new Scanner(System.in); String next = sc.next();
stream.write(next.getBytes());
|
释放资源
1 2
| stream.close(); socket.close();
|
TCP服务端
创建服务器端的socket
对象(ServerSocket
)
ServerSocket (int port)
创建绑定到指定端口的服务器套接字
1
| ServerSocket server = new ServerSocket(9000);
|
Socket accept()侦听要连接到此套接字并接受它
1
| Socket accept = server.accept();
|
accept() 阻塞式监听,会一直等待客户端连接
获取字节输入流和字节输出流
1 2
| InputStream stream = accept.getInputStream(); OutputStream outputStream = accept.getOutputStream();
|
接收数据
1 2 3 4 5 6
| byte[] buffer = new byte[1024]; int len; while ((len = stream.read(buffer))!=-1){ String msg = new String(buffer, 0, len); System.out.println(msg); }
|
这样写的缺点是,假如有中文,超过了1024,然后就断掉了。断掉之后就乱码了。
管道流
1 2 3 4 5 6 7
| byte[] buffer = new byte[1024]; int len; ByteArrayOutputStream baos = new ByteArrayOutputStream(); while ((len = stream.read(buffer))!=-1){ baos.write(buffer,0,len); } System.out.println(baos.toString());
|
关闭资源
1 2 3 4
| accept.close(); stream.close(); outputStream.close(); server.close();
|
案例
客户端发送消息字符串,服务端接收消息字符串。客户端输入“exit”结束发送,服务端发送“接收完毕”反馈,客户端接收反馈。
客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import java.io.*; import java.net.Socket; import java.util.Scanner;
public class Client { public static void main(String[] args) throws IOException { Socket socket = new Socket("localhost",10001);
OutputStream outputStream = socket.getOutputStream(); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));
Scanner sc = new Scanner(System.in); String text; while (!(text=sc.next()).equals("exit")){ bw.write(text); bw.newLine(); bw.flush(); }
socket.shutdownOutput();
System.out.println("END"); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line = br.readLine(); System.out.println(line);
socket.close(); bw.close(); } }
|
服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import java.io.*; import java.net.ServerSocket; import java.net.Socket;
public class Server { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(10001);
Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String text; while ((text = reader.readLine())!=null){ System.out.println(text); } OutputStream outputStream = accept.getOutputStream(); outputStream.write("接收完毕!".getBytes());
System.out.println("END"); accept.close(); serverSocket.close(); } }
|
关于shutdownOutput()
的作用:
socket.shutdownOutput()
:关闭客户端的输出流。相当于给流中加入一个结束标志-1,这个时候服务器端的输入流的readLine()
相当于读到了一个-1【null】,所以,就会结束while ((text = reader.readLine())!=null)
循环,接着往下执行。

IO流相关操作,参考我另一篇博客——Java-IO流
__END__