网络编程Socket

网络编程Socket

名词解释

互联网(Internet):又称国际网络,指的是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。
	点与点相连
万维网(www-world wide web):基于客户机/服务器方式的信息发现技术和超文本技术的综合。
	端与端相连
物联网(IOT-Internet of things):即“万物相连的互联网”,是互联网基础上的延伸和扩展的网络,将各种信息传感设备与网络结合起来而形成的一个巨大网络,实现任何时间、任何地点,人、机、物的互联互通.
	物与物相连
网络编程:
	让计算机与计算机之间建立连接,进行通讯

OSI网络架构

简介:
	Open System Interconnect
	开放式系统互连
	存在于概念和理论上的一种模型,它的缺点是分层太多,增加了网络工作的复杂性,所以没有大规模应用

img

img

一层:物理层为设备之间的数据通信提供传输信号和物理介质。(双绞线、 光导纤维)
作用:建立、维护、断开物理连接。
第二层:链路层在物理层上,通过规程或协议(差错控制)来控制传输数据的正确性。(MAC)
TCP/IP网络框架
IP协议
作用:接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,
拆装为位流形式的数据转发到物理层;并且,还负责处理接收端发回的确认帧的信息,以便提供可靠的数据传
输。
第三层:网络层负责定义了能够标识所有网络节点的逻辑地址。(IP地址)
作用:逻辑寻址,IP地址,在下两层的基础上向资源子网提供服务
第四层: 传输层负责是否选择差错恢复协议、数据流重用、错误顺序重排。(TCP、 UDP)
作用:提供可靠和不可靠的传输机制,TCP、UDP
第五层:会话层负责使应用建立和维持会话,使通信在失效时继续恢复通信。(断点续传).
作用:建立、终止、管理实体间的会话连接
第六层:表示层负责定义转换数据格式及加密,允许选择以二进制或ASCII格式传输。
作用:封装数据的格式(加密解密、压缩解压缩)
第七层:应用层负责文件访问和管理、可靠运输服务、远程操作服务。(HTTP、 FTP、SMTP)
作用:人与机器电脑交互的窗口

OSI模型数据传输流程

img

TCP/IP网络框架

img

TCP协议: Transmission Control Protocol传输控制协议
	是一种面向连接的、可靠的、基于字节流的传输层通信协议。数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手。
UDP协议: User Datagram Protocol用户数据报协议
	是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,每个包的大小64KB。

IP协议

简介:
	tnternet Protocol Address
	互联网协议地址/网际协议地址
	分配给互联网设备的数字标签(唯标识)。说人话就是计算机在互联网中的地址

IP地址分为两种:
	IPV4: 4字节32位整数,并分成48位的进制数,每8位之间用圆点隔开,每8位整数可以转换为一个
0~255的十进制整数。
	格式: D.D.D.D
	例如: 255.255.255.255

	IPV6: 16字节128位整数,并分成8段十六进制数,每1 6位之间用圆点隔开,每16位整数可以转换为一个0~65535的十进制数。
格式: X.X.X.X.X.X.X.X
例如: FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF

IPV4应用分类
    A:政府机构,1.0.0.1 ~ 126.255.255.254
    B:中型企业,128.0.0.1 ~ 191.255.255.254
    C:个人用户,192.0.0.1 ~ 223.255.255.254
    D:用于组播,224.0.0.1 ~ 239.255.255.254
    E:用于实验,240.0.0.1 ~ 255.255.255.254
    
回环地址: 127.0.0.1,指本机,一般用于测试使用。
查看IP命令: ipconfig
测试IP命令: ping D.D.D.D

对应类:InetAddress
	常用方法:
		public static InetAddress getLocalHost():获取本机地址
		如:
			InetAddress localHost = InetAddress.getLocalHost();
			System.out.println(localHost);
		打印结果:
			LAPTOP-RE2FI941/192.168.0.105
   
		public static InetAddress getByName(String host):通过主机名词获取地址
		如:
			InetAddress inetAddress = InetAddress.getByName("LAPTOPRE2FI941");
			System.out.println(inetAddress);
		打印结果:
			LAPTOP-RE2FI941/192.168.0.105
		注意:
			127.0.0.1,Localhost,域名都表示本机

		public static InetAddress[] getAllByName(String host):获取所有相关地址对象
		如:
			InetAddress[] addresses = InetAddress.getAllByName("www.baidu.com");
			for (InetAddress address : addresses) {
				System.out.println(address.getHostAddress()+"--"+address.getHostName());
			}
输出结果:
14.215.177.39--www.baidu.com
14.215.177.38--www.baidu.com

public String getHostAddress():获取主机地址
public String getHostName():获取主机名词

Port端口

端口号:在通信实体上进行网络通讯的程序的唯一标识。端口分类:
公认端口: 0~1023
注册端口: 1024~49151
动态或私有端口: 49152~65535
常用端口:
MySql: 3306
Oracle: 1521
Tomcat: 8080
SMTP: 25
Web服务器: 80
FTP服务器: 21
TCP/IP的数据传输流程

img

Socket编程

简介

Socket:套接字,网络中的一个节点
通讯要求:IP地址+端口号

TCP

简介:是一种面向连接的、可靠的、基于字节流的传输层通信协议。数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手。
注意:分为客户端Scoket与服务器ServerSocket
    
开发步骤:
    服务端:ServerSocket
        1,创建ServerSocket,指定端口
        2,调用accept等待客户端接入
        3,使用输入流,接收客户端请求中的数据
        4,使用输出流,给客户端回馈数据(可选)
        5,关闭释放资源
    客户端:Socket
        1,创建Socket对象,指定服务器IP+端口
        2,使用输出流,发起请求,给服务器发生数据
        3,使用输入流,接收服务器返回的数据(可选)
        4,关闭释放资源
代码:
	服务器:
    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.ServerSocket;
    import java.net.Socket;
    public class TcpServer {
        public static void main(String[] args) throws Exception{
            //1 创建ServerSocket 并指定端口号 设定服务器
            ServerSocket listener=new ServerSocket(服务器开放的端口);
            //2 调用accept(),接收客户端请求,阻塞方法(如果没有客户端请求,则阻塞)
            //此处获取得到的Socket的对象为客户端的镜像
            System.out.println("服务器已启动...");
            Socket socket=listener.accept();
            //3 获取输入流,读取客户端发送的数据
            InputStream is=socket.getInputStream();
            BufferedReader br=new BufferedReader(new
            InputStreamReader(is,"utf-8"));
            String data=br.readLine();
            System.out.println("客户发送:"+data);
            //4 获取输出流,发送数据给客户端[可选]
            //5 关闭释放资源
            br.close();
            socket.close();
            listener.close();
        }
    }
    客户端:
    import java.io.BufferedWriter;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.net.Socket;
    public class TcpClient {
    public static void main(String[] args) throws Exception{
            //1 创建客户端套接字,并指定服务器的地址和端口号,此时获取得到的Socket的对象为服务器的镜像
            Socket socket=new Socket(服务器IP, 服务器开放的端口);
            //2 获取输出流,发送数据给服务器
            OutputStream os=socket.getOutputStream();
            BufferedWriter bw=new BufferedWriter(new
            OutputStreamWriter(os,"utf-8"));
            bw.write("好久不见");
            //3 获取输入流,读取服务器回复的数据[可选]
            //4 关闭释放资源
            bw.close();
            socket.close();
        }
    }


客户端和服务端无限期通信
方法类:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class OneService {
	//Socket对象  
	private Socket socket;

	public OneService(Socket socket) {
		super();
		this.socket=socket;
	}

	public OneService() {
		super();
	}
	
	//服务端与客户端进行交互的方法
	public void fun(){
		//创建线程池
		ExecutorService pool = Executors.newFixedThreadPool(2);
		//客户端和服务端进行获取对方输入的数据并展示
		pool.submit(new Runnable() {
			@Override
			public void run() {
				try {
					//通过Socket对象获取字节输入流
					InputStream is = socket.getInputStream();
					//将字节流通过转换为字符转换流
					InputStreamReader reader = new InputStreamReader(is);
					//将转换流转为缓冲流
					BufferedReader br = new BufferedReader(reader);
					String str="";
					//读取到886则读取结束
					while(!str.equals("886")&&true) {
						//按行读取
						str=br.readLine();
						System.out.println(str);
					}
					//关闭流和Socket
					reader.close();
					br.close();
					socket.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				
			}
			
		});
		//服务端和客户端进行输入消息
		pool.submit(new Runnable() {
			@Override
			public void run() {
				try {	
					//通过Socket对象获取字节输出流
					OutputStream stream = socket.getOutputStream();
					//将字节流通过转换为字符转换流
					OutputStreamWriter os = new OutputStreamWriter(stream);
					//将转换流转为缓冲流
					BufferedWriter writer = new BufferedWriter(os);
					Scanner sc = new Scanner(System.in);
					String str="";
					//输入886表示结束
					while(!str.equals("886")&&true) {
						str=sc.next();
						writer.write(str);
						writer.newLine();
						writer.flush();
						
					}
					//关闭流和Socket
					os.close();
					writer.close();
					socket.close();
				} catch (UnknownHostException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			}
			
		});
		//关闭线程池
		pool.shutdown();
	}
}
服务端:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Demo {
	public static void main(String[] args) throws IOException {
		//设置服务端开放的端口
		ServerSocket sockets = new ServerSocket(9232);
		//等待客户端进行连接获取得到客户端镜像
		Socket socket = sockets.accept();
		//输出客户端网址
		System.out.println(socket.getInetAddress());
		//将客户端镜像传入OneService对象
		OneService oneService = new OneService(socket);
		//调用方法启动服务的线程
		oneService.fun();
	}
}
客户端:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class Test {

	public static void main(String[] args) throws UnknownHostException, IOException {
		//获取服务的镜像
		Socket socket = new Socket("10.35.162.54",9900);
		//将客户端镜像传入OneService对象
		OneService oneService = new OneService(socket);
		//调用方法启动服务的线程
		oneService.fun();
	}

}


进行客户端和服务的交互时,输入流与输出流需要注意的地方
	在通过输出流将数据输入到文件中,当输入结束后系统回自动在文件末添加EOF(结束标识符,值为-1);输入流在读取时读取到EOF时返回-1,表示文件读取结束,此时可将数据看着存放在内存中,数据末没有EOF进行结尾,因此在读取内存中的数据时在读取完后因为数据末没有EOF因此回进行无限期的等待.

UDP

简介:UDP协议是一种不可靠的网络协议,提供面向事务的简单不可靠信息传送服务,每个包的大小64KB,速率快
注意:分为接收端与发送端

开发步骤:
    发送端:
        1.创建发送端的Socket对象(DatagramSocket)
        2.创建数据,并打包
        3.调用DatagramSocket对象的方法发送数据
        4.关闭发送端
    接收端:
        1、创建接收端的Socket对象(DatagramSocket)
        2、创建一个数据包,用于接收数据
        3、调用DatagramSocket对象的方法接收数据
        4、解析数据包,并在控制台显示
        5、关闭接收端

代码:
    发送端:
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    public class UdpSend {
        public static void main(String[] args) throws IOException {
            //1,创建发送端Socket对象
            DatagramSocket socket = new DatagramSocket();
            //2,准备发送内容
            byte[] sendData = "要发送的内容".getBytes();
            //3,接收端地址
            InetAddress address = InetAddress.getByName(接收端的IP);
            //4,封装发送信息包
            DatagramPacket packet = new DatagramPacket(sendData,sendData.length, address, 9999);
            //5,发送信息
            socket.send(packet);
            //6,关闭发送端
            socket.close();
        }
    }
    接收端:
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    public class UdpGet {
        public static void main(String[] args) throws IOException {
            //1,创建接收端Socket
            DatagramSocket socket = new DatagramSocket(9999);
            //2,创建接收数据的包
            byte[] b = new byte[1024];
            DatagramPacket packet = new DatagramPacket(b, b.length);
            //3,等待接收数据
            socket.receive(packet);
            //4,获取数据
            byte[] data = packet.getData();
            //5,获取数据长度
            int length = packet.getLength();
            //6,打印输出
            System.out.println("接收的内容:"+new String(data,0,length));
            //7,关闭资源
            socket.close();
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值