**
简述JAVA中的TCP
**
TCP协议提供面向连接的服务。
Java为TCP协议提供了两个类:Socket类和ServerSocket类。
一个Socket实例代表了TCP连接的一个客户端,而一个ServerSocket实例代表了TCP连接的一个服务器端,再一般的TCP 编程中,客户端有多个,而服务器端只有一个,客户端向服务器端发送连接请求,服务器端的ServerSocket实例则监听来自客户端的TCP连接请求,并为每个请求创建新的Socket实例,由于服务端在调用accept()等待客户端的连接请求时会阻塞,直到收到客户端发送的连接请求才会继续往下执行代码。服务器端要同时处理ServerSocket实例和Socket实例,而客户端只需要使用Socket实例。另外,每个Socket实例会关联一个InputStream和OutputStream对象,我们通过将字节写入OutputStream来发送数据,并通过从InputStream来接收数据。
什么是Socket
Socket是一个抽象概念,一个应用程序通过一个Socket来创建一个远程连接,而Socket内部通过TCP/IP协议吧数据传输到网络。
JAVA提过的几个Socket相关的类就封装了操作习惯提供的接口:ServerSocket类,Socket类。
一个Socket就是由IP地址和端口号(0~65535)组成,可以把Socket简单理解为IP地址加端口号。
使用Socket进行网络编程的时候,本质上是两个进程之间的网络通信。其中一个进程必须当服务器端,它会知道监听某个指定的端口,零一个进程必须充当客户端,它必须主动连接服务器的IP地址和指定端口。
如果连接成功服务器端和客户端就成功地建立了一个TCP连接,双方后续就可以发送和接收数据,
服务器端
首先编写服务器端的程序 。
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket Socket= new ServerSocket(4567); // 监听指定端口
System.out.println("server is running...");
Socket sock = ss.accept();
System.out.println("connected from " + sock.getRemoteSocketAddress());
}
}
ServerSocket socket =new ServerSocket(4567);
//因为没有指定IP地址,在计算机的所有网络接口上进行监听。
如果ServerSocket监听成功,我们就使用一个无限循环来处理客户端的连接。
while (true) {
Socket socket = ss.accept();
System.out.println("connected from " + sock.getRemoteSocketAddress());
}
如果没有客户端连接进来,accept()方法会阻塞并一直等待。
客户端】
客户端比较简单
public class Client {
public static void main(String[] args) throws IOException {
// 连接指定服务器和端口
Socket sock = new Socket("你的ip", 4567);
sock.close(); System.out.println("disconnected.");
}
}
Socket流
当Socket连接创建成功后,TCP是一种基于流的协议,因此,JAVA标准库使用InputStrea和OutStream来封装Socket的数据流。
完整的一个TCP协议
在JAVA中一个完整的TCP,需要IO流和Socket,服务器,客户端。具体实现如例子如下:
客户端:
public static void main(String[] args) {
try (//客户端
//边读边写输出字节流
Socket sock = new Socket("IP",5678);
//利用带缓冲区的输入流来读取文件
BufferedInputStream in = new BufferedInputStream(
new FileInputStream("C:\\Users\\zero\\Pictures\\Saved Pictures\\1015424.jpg"))) {
byte[] buff = new byte[1024];
int len =-1;
//获得Socket的输出流
OutputStream out = sock.getOutputStream();
while((len = in.read(buff))!=-1) {
//输出字节
out.write(buff);
}
//告诉它你发完了,现在暂时挂起,还不关闭,等待回应
sock.shutdownOutput();
//获得服务器的反馈创建一个字符读取流
try (BufferedReader reader = new BufferedReader( new InputStreamReader(sock.getInputStream()))) {//这里把字节流转换成字符流
String reply = reader.readLine();
System.out.println("服务器的反馈"+reply);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
服务器
public static void main(String[] args) {
try (
ServerSocket ss = new ServerSocket(5678);
//如果有客户端连接时,该方法返回此客户端的Socket
Socket client = ss.accept();
//InetAddress clientNetAddress =client.getInetAddress();
//得到从网络输出到本机的输出流
OutputStream out = new FileOutputStream("C:\\Users\\zero\\Pictures\\Saved Pictures\\123145.jpg");
BufferedInputStream in = new BufferedInputStream(client.getInputStream())) {
byte[] buff = new byte[1024];
int len =-1;
//创建网络的输入流,得到客户端发出的文件
while((len = in.read(buff))!=-1) {
out.write(buff, 0, len);
}
try (BufferedWriter writer = new BufferedWriter( new OutputStreamWriter( client.getOutputStream()))) {
writer.write("upload successed!!!");
writer.newLine();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}