概述
* 网络编程
* 体系结构 - OSI TCP/IP 五层协议
* 交互信息:
* 主机1 -》 主机2
* 应用程序1 -》 应用程序2
* 主机1的第5层(应用层) -》 加上必要的控制信息H5 -> 变成下一层所需要数据单元 -》
* 到达主机1第4层(运输层) -》 加上必要的控制信息H4 -》
* 到达主机1第3层(网络层) -》控制信息分为两部分 H2 T2 -》
* 到达主机1第2层(数据链路层) -》比特流 -》
* 到达主机1第1层(物理层) -》主机2
*
* 数据传输控制协议(TCP协议)
* TCP协议是面向连接的传输层协议
* TCP协议采用字节流机制传输数据
* TCP特点:
* 1)提供可靠交付服务,通过TCP连接传输的数据,无差错、不丢失、不重复
* 2)提供全双工通信
* 3)面向字节流,点对点通信
*
* 网络通信两要素:主机 ip
* 端口 port
*
* TCP编程
* Java Socket
* socket称之为"套接字",用于描述IP地址和端口号,是一个通信的句柄。
* 应用程序通过套接字向网络中发送请求或者应答请求 (客户端 《-》 服务器)
* Socket java.net 用于客户端
* ServerSocket 用于服务器端
*
* 客户端
* Socket常用API
* · Accept 用于产生"阻塞",直到接收一个连接,并且返回一个客户端的Socket
* 对象实例
* 服务器端使用,如果该方法有返回值,说明此时有一个客户端请求当前服务器端,接下来
* 的操作都需要使用这样的一个返回值
* · getInputStream 获取网络连接的输入
* · getOutputStream 获取网络连接的输出
*
* 服务器端
* 构造ServerSocket
* ServerSocket()
* ServerSocket(int port)
* ServerSocket(int port, int backlog)
* ServerSocket(int port, int backlog, InetAddress bindAddr)
*
* backlog参数用来设置连接请求队列的长度
单线程客户端和服务器
客户端
public class MyTcpclient {
public static void main(String[] args) {
Socket socket = null;
BufferedReader input = null;
PrintWriter output = null;
BufferedReader reader = null;
try {
//构造Socket
try {
socket = new Socket("127.0.0.1", 3333);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("客户端已经启动...");
while(true){
//发送数据到服务器端
//获取控制台的输入流
input = new BufferedReader(new InputStreamReader(System.in));
String info = input.readLine();
//获取连接对象的输出流
output = new PrintWriter(socket.getOutputStream());
System.out.println("debug-info: "+info);
//输出流对象写入info数据
output.println(info); //tcp存在缓冲区,有可能缓冲区没有刷新就导致数据无法传输
output.flush();
//输出服务器端返回的数据
//获取连接对象的输入流
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String strs = reader.readLine();
System.out.println("客户端显示--服务器端响应的数据:"+strs);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
reader.close();
input.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
服务器端
public class MyTcpServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
BufferedReader reader = null;
PrintWriter output = null;
BufferedReader input = null;
try {
//构造ServerSocket对象 监听3333
serverSocket = new ServerSocket(3333);
System.out.println("服务器端已经启动...");
//等待接收客户端的请求
Socket accept = serverSocket.accept();
System.out.println("连接建立成功...");
while(true){
// //从客户端的socket实例获取网络中数据
// InputStream inputStream = accept.getInputStream();
// //转换为字符流
// InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
// //缓冲流
// BufferedReader reader = new BufferedReader(inputStreamReader);
//获取连接对象的输入流
reader = new BufferedReader(new InputStreamReader(accept.getInputStream()));
//获取客户端的输入信息
String strs = reader.readLine();
System.out.println("服务端显示 -- 客户端"+accept.getRemoteSocketAddress()+"的数据:"+strs);
//回复
//获取连接对象的输出流
output = new PrintWriter(accept.getOutputStream());
//获取控制台的输入流
input = new BufferedReader(new InputStreamReader(System.in));
String info = input.readLine();
//输出流对象写入输出信息
output.println(info);
output.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
serverSocket.close();
reader.close();
input.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
多线程下多个客户端访问服务器
服务器端
class thread1 extends Thread{
private Socket socket;
public thread1(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader reader = null;
OutputStream outputStream = null;
//进行通信
try {
while(true){
//进行读操作
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String msg = reader.readLine();
System.out.println("客户端:"+socket.getRemoteSocketAddress()+"发送信息:"+msg);
//进行写操作
outputStream = socket.getOutputStream();
outputStream.write(("reponse: "+msg+"\n").getBytes());
if("".equals(msg) || "exit".equals(msg)){
System.out.println("lvting-Debug");
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class MulitThread_TcpServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(3333);
while(true){
//进行监听,等待多个客户端连接
Socket accept = serverSocket.accept();
System.out.println("与客户端:"+accept.getRemoteSocketAddress()+ "连接建立成功...");
//将accpet实例交给子线程处理客户端请求
new thread1(accept).start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端
public class MulitThread_Tcpclient {
public static void main(String[] args) {
Socket socket = null;
BufferedReader input = null;
PrintWriter output = null;
BufferedReader reader = null;
try {
//构造Socket
socket = new Socket("127.0.0.1", 3333);
System.out.println("客户端已经启动...");
while(true){
//发送数据到服务器端
//获取控制台的输入流
input = new BufferedReader(new InputStreamReader(System.in));
String info = input.readLine();
//获取连接对象的输出流
output = new PrintWriter(socket.getOutputStream());
System.out.println("debug-info: "+info);
//输出流对象写入info数据
output.println(info); //tcp存在缓冲区,有可能缓冲区没有刷新就导致数据无法传输
output.flush();
//输出服务器端返回的数据
//获取连接对象的输入流
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String strs = reader.readLine(); //阻塞
System.out.println("客户端显示--服务器端响应的数据:"+strs);
if("".equals(strs) || "exit".equals(strs)){
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
reader.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}