网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;
HTTP与socket的关系:
- HTTP是轿车,提供了封装或者显示数据的具体形式。
- Socket是发动机,提供了网络通信的能力。
socket通讯分为tcp和udp
tcp通讯就像打电话一样,只有两端建立好连接后才能传输数据,而udp则像发短信一样,不需要直接建立连接,upd通讯是不稳定的,UDP不能保证消息被传送到(它也报告消息没有传送到)目的地。UDP也不保证数据包的传送顺序。UDP把数据发出去后只能希望它能够抵达目的地。
tcp与upd协议流程图
tcp服务端实现:
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;public class SocketServer {
public static void main(String[] args) {
try {// 1、创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
ServerSocket ss = new ServerSocket(8989);// 2、调用accept()方法开始监听,等待客户端的连接
Socket accept = ss.accept();
System.out.println("客户端连接成功");// 3、获取输入流,并读取客户端信息
BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());InputStreamReader isr = new InputStreamReader(bis);
BufferedReader br = new BufferedReader(isr);
String str = null;
while ((str = br.readLine()) != null) {
System.out.println("客户端说:" + str);
}
System.out.println("连接关闭");
} catch (IOException e) {
e.printStackTrace();
}
}}
tcp客户端实现
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;public class SocketClient {
public static void main(String[] args) {
try {
// 创建客户端连接服务端
Socket s = new Socket("localhost", 8989);// 获取客户端输出流,写入数据
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());OutputStreamWriter osw = new OutputStreamWriter(bos, "utf-8");
BufferedWriter bw = new BufferedWriter(osw);
while (true) {
Scanner scan = new Scanner(System.in);
String nextLine = scan.nextLine();
if (nextLine.equals("q"))
break;
else {
bw.write(nextLine);
bw.newLine();
bw.flush();
}}
bw.close();
osw.close();
bos.close();
s.close();} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}}
Udp服务端实现
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class SocketServer {
public static void main(String[] args) throws IOException {
// 服务器端,实现基于UDP的用户登录
// 1、创建服务器端DatagramSocket,指定端口
DatagramSocket socket = new DatagramSocket(9090);
// 2、创建数据报,用于接受客户端发送的数据
byte[] data = new byte[1024];//
DatagramPacket packet = new DatagramPacket(data, data.length);
// 3、接受客户端发送的数据
socket.receive(packet);// 此方法在接受数据报之前会一致阻塞
// 4、读取数据
String info = new String(data, 0, data.length);
System.out.println("我是服务器,客户端告诉我:" + info);// =========================================================
// 向客户端响应数据
// 1、定义客户端的地址、端口号、数据
InetAddress address = packet.getAddress();
int port = packet.getPort();
byte[] data2 = "欢迎您!".getBytes();
// 2、创建数据报,包含响应的数据信息
DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
// 3、响应客户端
socket.send(packet2);
// 4、关闭资源
socket.close();
}}
Udp客户端实现
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class SocketClient {
public static void main(String[] args) throws IOException {
// 客户端
// 1、定义服务器的地址、端口号、数据
InetAddress address = InetAddress.getByName("localhost");
int port = 9090;
byte[] data = "用户名:admin;密码:123".getBytes();
// 2、创建数据报,包含发送的数据信息
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
// 3、创建DatagramSocket对象
DatagramSocket socket = new DatagramSocket();
// 4、向服务器发送数据
socket.send(packet);// 接受服务器端响应数据
// ======================================
// 1、创建数据报,用于接受服务器端响应数据
byte[] data2 = new byte[1024];
DatagramPacket packet2 = new DatagramPacket(data2, data2.length);
// 2、接受服务器响应的数据
socket.receive(packet2);
String raply = new String(data2, 0, packet2.getLength());
System.out.println("我是客户端,服务器说:" + raply);
// 4、关闭资源
socket.close();}
}
参考文档:https://blog.csdn.net/zkkzpp258/article/details/80863958