1.TCP通信
1.1TCP通信简介
TCP通信与UDP通信一样,都可以实现两台计算机之间的通信,通信的两端都需要创建Socket对象。它们之间的一个主要区别在于TCP严格区分客户端和服务器端,在通信时必须先由客户端去连接服务器端才能实现通信,服务器端得等待客户端连接服务器。UDP只有发送端和接收端,不区分客户端和服务器端。
两者通信过程:
通信时,首先要创建代表服务器端的ServerSocket对象,该对象相当于开启一个服务,并等待客户端的连接;然后创建代表客户端的Socket对象,并向服务器端发出连接请求,服务器端响应请求,两者建立连接后就可以正式进行通信。
1.2ServerSocket
构造方法:ServerSocket(int port)
使用该构造方法创建ServerSocket对象时,可以将其绑定到指定的端口上。如果port参数值为0,此时系统就会分配一个未被其他程序占用的端口号。由于客户端需要根据指定的端口号来访问服务器程序,因此端口号随机分配的情况并不常用,通常我们还是需要指定一个端口号。
ServerSocket对象负责监听某台客户端计算机的端口号,在创建ServerSocket对象后,需要调用这个对象的accept()方法,接收来此客户端的请求。当执行了accept()方法之后,服务器端程序会发生阻塞,指导客户端发出连接请求,accept()方法才会返回一个socket对象用于和客户端进行通信,程序才能继续向下进行。
1.3Socket
构造方法:Socket(String host,int port):该构造方法在创建Socket对象时,会根据参数去连接指定地址和端口上运行的服务器程序,其中host接受的是一个字符串类型的IP地址,port即一个端口号。
主要方法:
1>void close():该方法用于关闭Socket连接,结束本次通信。在关闭Socket之前,应将与Socket相关的所有输入输出流全部关闭,这是因为一个良好的程序应该在执行完毕时释放所有的资源。
2>InputStream getInputStream():该方法返回一个InputStream类型的输入流对象。如果该对象是由服务器端Socket返回,就用于读取客户端发送的数据;反之用于读取服务器端发送的数据。
3>OutputStream getOutputStream():该方法返回一个OutputStream类型的输出流对象。如果该对象是由服务器端的Socket返回,就用于向客户端发送数据;反之用于向服务器端发送数据。
当服务器端和客户端建立连接后,数据是以I/O流的形式进行交互,从而实现通信的。
1.4实现
实现1:服务器端
import javax.servlet.ServletContext;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
TCP通信的服务器端:接收客户端的请求,读取服务器端发送的数据,给客户端写数据
*/
/*
明确:
必须使用accept()方法来获取请求的客户端对象socket
步骤:
1.创建服务器ServerSocket对象,和系统指定的端口号
2.使用ServerSocket对象中的accept()方法获取到请求的服务器端对象Socket
3.使用Socket对象中的getInputStream()方法获取网络字节输出流InputStream对象
4.使用网络字节输出流对象InputStream对象中的方法read(),读取客户端发送的数据
5.使用Socket对象中的getOutputStream()方法获取网络字节输出流OutputStream对象
6.使用网络字节输出流对象OutputStream对象中的方法write(),给客户端回写数据
7.释放资源Socket,ServerSocket
*/
public class TCPServer {
public static void main(String[] args) throws IOException {
//1.创建服务器ServerSocket对象,和系统指定的端口号
ServerSocket serverSocket=new ServerSocket(8888);
while(true){
//2.使用ServerSocket对象中的accept()方法获取到请求的服务器端对象Socket
Socket socket=serverSocket.accept();
int port=socket.getPort();
System.out.println("与端口号为"+port+"客户端连接成功,开始进行数据交互");
//3.使用Socket对象中的getInputStream()方法获取网络字节输出流InputStream对象
InputStream is=socket.getInputStream();
//4.使用网络字节输出流对象InputStream对象中的方法read(),读取客户端发送的数据
byte[] bytes=new byte[1024];
int len=is.read(bytes);
System.out.println(new String(bytes,0,len));
//5.使用Socket对象中的getOutputStream()方法获取网络字节输出流OutputStream对象
OutputStream os=socket.getOutputStream();
//6.使用网络字节输出流对象OutputStream对象中的方法write(),给客户端回写数据
os.write("收到,谢谢".getBytes());
//7.释放资源Socket,ServerSocket
socket.close();
serverSocket.close();
}
}
}
实现2:客户端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/*
TCP通信的客户端,向服务器发送连接请求给服务器发送数据
*/
/*
实现步骤:
1.创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号
2.使用Socket对象中的getOutputStream()方法获取网络字节输出流OutputStream对象
3.使用网络字节输出流对象OutputStream对象中的方法write(),给服务器发送数据
4.使用Socket对象中的getInputStream()方法获取网络字节输出流InputStream对象
5.使用网络字节输出流对象InputStream对象中的方法read(),读取服务器发送的数据
6.释放资源
*/
public class TCPClient {
public static void main(String[] args) throws IOException {
//1.创建一个Socket并连接到指定的服务器端
Socket socket =new Socket("127.0.0.1",8888);
//2.使用Socket对象中的getOutputStream()方法获取网络字节输出流OutputStream对象
OutputStream os=socket.getOutputStream();
//3.使用网络字节输出流对象OutputStream对象中的方法write(),给服务器发送数据
os.write("你好,服务器".getBytes());
//4.使用Socket对象中的getInputStream()方法获取网络字节输出流InputStream对象
InputStream is=socket.getInputStream();
//5.使用网络字节输出流对象InputStream对象中的方法read(),读取服务器发送的数据
byte[] bytes=new byte[1024];
int len=is.read(bytes);
System.out.println(new String(bytes,0,len));
//6.释放资源
socket.close();
}
}
1.5运行结果:
步骤:
1.先启动服务器端,等待客户端连接请求。其中使用accept()方法持续监听客户端连接。
2.客户端与服务器端建立连接,accept()方法监听到,此时服务器端程序阻塞。
3.客户端访问服务器端结束这种阻塞状态。