第一篇文章,我先介绍以及记录一下我所学的知识点。(总结了一下视频老师讲的东西)
一,HTTP与Socket
1.HTTP:超文本传输协议
特点:客户端发送的请求需要服务器端每次来响应,在请求结束之后主动释放连接,从建立连接到关闭连接称为“一次连接”,所以HTTP是“短连接”。
2.Socket(IP+PORT):是TCP/IP的封装与应用,它不是协议,而是API
特点:客户端与服务器之间一旦建立连接,就可以互相范松消息,也叫对话,但在实际应用中,通信双方经过许多的中间节点,比如,路由器,网关,防火墙,大部分防火墙会默认关闭长时间处于不活跃的状态连接,而是Socket断开。
选择:当服务器主要想客户端推送消息,为了保持客户端与服务器数据的实时与同步,通常会从采用HTTP协议,只要客户端定时向服务器端发送请求,同时也是在询问是否有新的数据,如果有那就传入客户端。
二,TCP/IP模型
1.通信原理图
2.模型图
三,基于TCP的网络编程
1.Socket: IP地址+端口号组成了Socket,Socket是网络上运行程序之间双向通信的终结点,是TCP和UDP的基础。
2.JAVA提供的网络功能(可以查看API)
InetAddress:标识IP地址
URL:统一资源定位,通过URL可以直接读取或写入网络上的数据
Sockets:使用TCP协议实现Socket相关的类
Datagram:使用UDP协议。将数据保存在数据包中,通过网络通信。
3.Socket通信模型
4.代码(可直接粘贴复制,使用)请修改包名
1.服务器端线程类 ServerThread.class
//*******************服务器端线程类********************//
package com.NullChenHui;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class ServerThread extends Thread {
private int port;
private boolean OVER_FLAG = false;
public ServerThread(int port) {
this.port = port;
}
@Override
public void run() {
// TODO Auto-generated method stub
/**
* 使用无线循环或者有限循环来实现客户端与服务器的对话
*/
try {
//1.创建连接服务器的Socket 并绑定端口号
ServerSocket ssocket = new ServerSocket(port);
while(!OVER_FLAG) {
//2.监听来自客户端的请求 并返回Socket实例
Socket socket = ssocket.accept();
//3.获取输入流
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is); //字节流包装为字符流
BufferedReader bf = new BufferedReader(isr); //添加进缓存
//4.从缓存中读取数据
String info = null;
if("OVER".equals(info)) {
OVER_FLAG = true;
break;
}
while((info=bf.readLine()) != null) {
System.out.println("客户端说:"+info);
if("OVER".equals(info)) {
OVER_FLAG = true;
break;
}
}
socket.shutdownInput();
String data = null;
System.out.print("服务端:");
Scanner scanner = new Scanner(System.in);
String data1 = scanner.nextLine();
//回馈给客户端
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
//3.发送数据
pw.write(data1);
pw.flush();
//4.关闭资源
os.close();
pw.close();
is.close();
bf.close();
// socket.shutdownOutput();
}
System.out.println("对话结束");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2.服务器端主程序 MyServerSocket.class
package com.NullChenHui;
/**
* 基于TCP的Socket的编程 服务端
* @author NullChen
*
*/
public class MyServerSocket{
@SuppressWarnings("resource")
public static void main(String[] args) {
System.out.println("***我是服务器***");
ServerThread sThread = new ServerThread(3333);
sThread.start();
}
}
3.客户端线程类 ClientThread.class
package com.NullChenHui;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class ClientThread extends Thread {
private String IP;
private int port;
private boolean OVER_FLAG = false;
public ClientThread(String IP ,int port) {
this.IP = IP;
this.port = port;
}
@Override
public void run() {
// TODO Auto-generated method stub
OutputStream os =null;
PrintWriter pw = null;
try {
//1.建立客户端Socket 并指定发送服务器端的地址(IP + port )
//2.获取输出流
while(!OVER_FLAG) {
Socket socket = new Socket(IP,port);
os = socket.getOutputStream();
pw = new PrintWriter(os);
//3.发送数据
System.out.print("客户端:");
Scanner scanner = new Scanner(System.in);
String data1 = scanner.nextLine();
pw.write(data1);
pw.flush();
//4.关闭资源
socket.shutdownOutput();
//接受来自服务器的反馈
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is); //字节流包装为字符流
BufferedReader bf = new BufferedReader(isr); //添加进缓存
//4.从缓存中读取数据
String info = null;
while((info=bf.readLine()) != null) {
System.out.println("服务器说:"+info);
if("OVER".equals(info)) {
OVER_FLAG = true;
break;
}
}
/***
* 如果获取的内容是空的 说明服务器端还没有发送数据
*/
// 5 关闭资源
os.close();
pw.close();
is.close();
bf.close();
// socket.shutdownInput();
}
System.out.println("对话结束");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4.客户端主程序 MyClientSocket.class
package com.NullChenHui;
public class MyClientSocket{
public static void main(String[] args) {
System.out.println("***我是客户端***");
ClientThread cThread = new ClientThread("127.0.0.1",3333);
cThread.start();
}
}
四,注意问题
1.先启动服务器端后启动客户端
2.两个之间的对话就是客户端说一句,服务器说一句。
3.以客户端以OVER结束对话
4.在关闭输入输出流的地方有点小问题。
五,欢迎大家指正。