1. 概述
通信步骤
服务器端先启动,服务器端不会主动的请求客户端,必须使用客户端请求服务器端。客户端和服务器端会建立一个逻辑链接,而这个连接中包含一个IO对象,客户端使用这个IO对象进行通信。通信的数据不只是字符,所以是字节流对象。
服务器端必须明确两件事
多个客户端同时和服务器端进行交互,服务器端必须明确和哪个客户端进行的交互。服务器端有个方法,叫accept客户端获取到请求的客户端对象。
多个客户端同时和服务器进行交互,就需要使用多个IO流对象。
服务器端是没有IO流的,服务器可以获取到请求的客户流对象Socket,使用每个客户端Socket中提供的IO流和客户端进行交互。
服务器端使用客户端的字节输入流读取客户端发送数据
服务器端使用客户端的字节输出流给客户端回写数据
在Java中提供了两个类实现TCP通信程序
- 客户端:
java.net.Socket
类表示,创建Socket
对象,向服务端发出连接请求,服务器端响应请求,两者建立连接开始通信
- 服务端:
java.net.SeverSocket
类表示。创建SeverSocket
对象,先当与开启一个服务,并等待客户端的连接
2. Socket类
Socket
类:该类实现客户端套接字(两台设备之间通讯的端点)
public Socket(String host,int port)
:创建套接字对象并将其连接到指定主机上的指定端口号。如果指定的host是null,则相当于指定地址为回送地址。
OutputStream getOutputStream()
:返回此套接字的输出流
InputStream getInputStream
:返回此套接字的输入流
void close()
:关闭此套接字
3. SeverSocket类
SeverSocket(int port)
:创建绑定到端口的服务器套接字
- Socket accept():侦听并接收此套接字的连接
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 32 33 34 35 36 37 38 39
| public class TCPClient { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.0.1", 8888); OutputStream os = socket.getOutputStream(); os.write("你好,服务器".getBytes()); InputStream is = socket.getInputStream(); byte[] bytes = new byte[1024]; int len = is.read(bytes); System.out.println(new String(bytes, 0, len)); socket.close(); } }
public class TCPSever { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(8888); Socket socket = server.accept(); InputStream is = socket.getInputStream(); byte[] bytes = new byte[1024]; int len = is.read(bytes); System.out.println(new String(bytes, 0, len)); OutputStream os = socket.getOutputStream(); os.write("收到谢谢".getBytes()); socket.close(); server.close(); } }
|
文件上传案例
当客户端向服务器发送数据时,不会将结束标记发送过去,服务器将会处于循环等待,所以要使用shutdownOutput方法。
void shutdownOutput()
:禁用此套接字的输出流。对于TCP套接字,任何以前写入的数据都将被发送,并且后跟TCP的正常连接终止序列
为防止同名文件被覆盖,自定义一个文件的命名规则:域名+毫秒值+随机数
服务器要一直处于监听状态(死循环accept方法)。使用多线程技术,提高程序的效率,有一个客户端上传文件就开启一个线程,完成文件上传
服务器端代码
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 32 33 34 35 36 37 38 39 40 41 42 43
| public class TCPSever { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(8888); while (true){ Socket socket = server.accept(); new Thread(new Runnable() { @Override public void run() { try{ File file = new File("D:\\Blog\\images\\JAVA"); if(!file.exists()){ file.mkdirs(); } String filename = "hxx"+System.currentTimeMillis()+ new Random(9999).nextInt(); FileOutputStream fos = new FileOutputStream(file+"\\"+filename+".png");
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024]; int len; while ((len = is.read(bytes))!=-1){ fos.write(bytes,0,len); } OutputStream os = socket.getOutputStream(); os.write("上传成功".getBytes()); socket.shutdownOutput(); }catch (IOException e){ System.out.println(e); } } }).start(); } } }
|
客户端代码
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
| public class TCPClient { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("xin.png"); Socket socket = new Socket("127.0.0.1", 8888); OutputStream os = socket.getOutputStream();
byte[] bytes = new byte[1024]; int len = 0; while ((len = fis.read(bytes))!= -1){ os.write(bytes,0,len); } socket.shutdownOutput();
InputStream is = socket.getInputStream(); len = 0; while ((len = is.read(bytes))!= -1){ System.out.println(new String(bytes,0,len)); } socket.close(); fis.close(); } }
|
模拟BS服务器代码
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| public class BSserver { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(8080); while(true){ Socket socket = server.accept(); new Thread(new Runnable() { @Override public void run() { try { InputStream is = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String s = br.readLine(); String[] s1 = s.split(" "); String htmlPath = s1[1].substring(1);
FileInputStream fis = new FileInputStream(htmlPath); OutputStream os = socket.getOutputStream(); os.write(("HTTP/1.1 200 OK\r\n").getBytes()); os.write(("Content-Type:text/html\r\n").getBytes()); os.write(("\r\n").getBytes());
byte[] bytes = new byte[1024]; int len = 0; while ((len = fis.read(bytes)) != -1) { os.write(bytes, 0, len); } fis.close(); socket.close(); }catch (IOException e){ System.out.println(e); } } }).start(); } } }
|