Java 网络编程 Java 全面掌握网络编程篇
青素i 人气:0计算机网络
是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。包括局域网(intranet)和广域网(internet)
网络模型
网络模型一般是指
○ OSI(Open System Interconnection开放系统互连)参考模型
○ TCP/IP参考模型
网络编程 就是用来实现网络互联的不同计算机上运行的程序间可以进行数据交换。
计算机网络之间以何种规则进行通信,就是网络模型研究问题
客户机服务器模式(Client/Server)
●为了实现两台计算机的通信,必须要用一个网络线路连接两台计算机。
● 服务器(Server)是指提供信息的计算机或程序
●客户机(Client)是指请求信息的计算机或程序
●网络用于连接服务器与客户机,实现两者相互通信。
TCP/IP的概念和实现
TCP/IP:Transmission Control Protocol/Internet Protocol的简写。TCP 是传输控制协议的缩写,它保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称 TCP / IP。
TCP三次握手(Three-way handshake)
所谓的“三次握手”即对每次发送的数据量是怎样跟踪进行协商使数据段的发送和接收同步,根据所接收到的数据量而确定的数据确认数及数据发送、接收完毕后何时撤消联系,并建立连接。
❤ 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;
SYN:同步序列编号(Synchronize Sequence Numbers)。
❤ 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(seq=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
❤ 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ETABLISHED(TCP连接成功)状态,完成三次握手。
❤ 完成三次握手,客户端与服务器开始传送数据
TCP编程
套接字(Socket)是使用TCP提供了两台计算机之间的通信机制。
客户端程序创建一个套接字,并尝试连接服务器的套接字。
当连接建立时,服务器会创建一个 Socket 对象。客户端和服务器现在可以通过对
Socket 对象的写入和读取来进行通信。
► 服务端:
创建服务端对象,监听一个端口
ServerSocket ss = new ServerSocket(100);
获取客户端对象
Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress();
► 客户端:
创建客户端socket服务,把ip和端口作为地址传进构造函数
Socket s = new Socket("localhost",100);
UDP的概念和实现
UDP(User Datagram Protocol):UDP 是用户数据报协议的缩写,一个无连接的协议。提供了应用程序之间要发送的数据的数据包。
用户数据包协议(UDP)是网络信息传输的另一种形式,基于UDP的通信与基于TCP的通信不同,UDP的信息传递更快,但不提供可靠的保证。
UDP编程
发送端:
建立udp服务,发送端没有指定端口,会自动分配一个端口
DatagramSocket ds = new DatagramSocket();
定义数据内容,并将数据封装成包
byte[] bt = “hello,udp,我来了”.getBytes();
把要发送的数据和ip、port封装到数据包里
DatagramPacket db = new
DatagramPacket(bt,bt.length,InetAddress.getByName(“192.168.1.105”),10000);
通过udp的socket服务中的功能完成数据包的发送 ds.send(db);
接收端:定义socket服务,监听端口
DatagramSocket ds = new DatagramSocket(10000);
预先定义好一个数据包,用于存储接收到的数据
byte[] bt = new byte[1024];
创建数据包对象,用于接收数据
DatagramPacket dp = new
DatagramPacket(bt,bt.length);
使用socket服务的receive方法将接受到的数据存储到数据包中
ds.receive(dp);
通过数据包对象,获取数据包内容
byte[] data = dp.getData();
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
TCP和UDP的区别
TCP:
1,面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中需要连接时间。
2,TCP传输数据无大小限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大的数据。
3,TCP是一个可靠的协议,它确保接收方完全正确地获取发送方所发送的全部数据。
UDP:
1,每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。
2,UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。
3,UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方
TCP和UDP最大的区别在于是否需要客户端与服务端建立连接后才能进行数据传输。
聊天室
服务器处理线程
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.Reader; import java.net.Socket; import java.net.SocketException; import java.util.Scanner; public class ServerTask implements Runnable{ private Socket socket; public ServerTask(Socket socket) { // TODO 自动生成的构造函数存根 this.socket = socket; } @Override public void run() { // TODO 自动生成的方法存根 //建立通信后所执行的内容 System.out.println("欢迎【"+socket.getRemoteSocketAddress().toString()+"】进入聊天室"); //构建读取缓冲 BufferedReader br =null; //http响应写入 PrintWriter pw = null; try { //获取客户端输入的信息 字节流缓冲成字符流 br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String msg; while((msg=br.readLine()) != null) { msg = "【"+socket.getRemoteSocketAddress().toString()+"】说"+msg; //输出客户端信息 System.out.println(msg); //服务器接收到客户端的消息发送消息给客户端 Scanner scanner = new Scanner(System.in); System.out.println("请输入要发送的信息!"); pw = new PrintWriter(socket.getOutputStream(),true); pw.println("服务器说:"+scanner.nextLine()); pw.flush(); } }catch (SocketException e) { // TODO: handle exception System.out.println(socket.getRemoteSocketAddress().toString()+"退出聊天室!"); } catch (Exception e) { // TODO: handle exception } } }
客户端处理线程
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintStream; import java.io.PrintWriter; import java.net.Socket; import java.net.SocketException; import java.util.Scanner; public class ClientTask implements Runnable{ private Socket socket; public ClientTask(Socket socket) { // TODO 自动生成的构造函数存根 this.socket = socket; } @Override public void run() { // TODO 自动生成的方法存根 try { while(true) { Scanner scanner = new Scanner(System.in); System.out.println("请输入要发送的信息"); //消息发送到服务器 PrintWriter pw = new PrintWriter(socket.getOutputStream(),true); //br.readLine()读取的消息发送到服务器 pw.println(scanner.nextLine()); //读取服务器发送的消息 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); System.out.println(br.readLine()); } } catch (Exception e) { // TODO: handle exception } } }
服务器
import java.net.ServerSocket; import java.net.Socket; import com.qingsu.chat.Task.ServerTask; public class ChatServer { public static void main(String[] args) { try { //创建服务端对象 监听一个窗口 ServerSocket serverSocket = new ServerSocket(10622); System.out.println("服务器创建成功!端口号"+10622); //阻塞 直到有链接返回 while(true) { Socket socket = serverSocket.accept();//获取客户端对象 //启动一个线程处理该链接 Thread thread = new Thread(new ServerTask(socket)); thread.start(); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }
客户端
import java.net.Socket; import com.qingsu.chat.Task.ClientTask; public class ChatClient { public static void main(String[] args) { try { //创建客户端socket服务,把ip和端口作为地址传进构造函数 Socket socket = new Socket("127.0.0.1",10622); //启动客户机线程处理 Thread thread = new Thread(new ClientTask(socket)); thread.start(); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }
效果
加载全部内容