网络编程及套接字

2024-01-14 12:30
文章标签 编程 网络 接字 及套

本文主要是介绍网络编程及套接字,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

IP地址

IP地址介绍

 IP地址的配置和检测

 网络通信协议

 套接字(Socket)

 基于TCP协议的Socket编程

多线程处理多请求

UDP数据报

基于UDP协议的Socket编程 


相互连接的计算机通过网络进行数据的交换和资源共享

IP地址

IP地址介绍

                计算机之间相互通信,也是需要地址的,即IP地址

        IP地址的组成

        IP地址(Internet Protocol):唯一标识网络上的每一台计算机

        IP地址:32位,由4个8位二进制组成.IP地址通常用“点分十进制”表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之间的十进制整数。例:点分十进IP地址(100.4.5.6),实际上是32位二进制数(01100100.00000100.00000101.00000110)。

        IP地址 = 网络地址 +主机地址

        网络地址:标识计算机或网络设备所在的网段

        主机地址:标识特定主机或网络设备

分为A,B,C,D,E五类地址

 IP地址的配置和检测

查看IP地址,检测网络是否畅通

查看本机的IP地址

ipconfig

 测试网络是否通畅

ping  目标IP地址

 网络通信协议

为了在网络中不同的计算机之间进行通信而建立的规则、标准或约定的集合

 

 套接字(Socket)

        网络通信使用IP地址标识Internet.上的计算机,使用端口号标识服务器上的进程(程序)。也就是说,如果服务器上的一个程序不占用-一个端口号,用户程序就无法找到它,就无法和该程序交互信息。端口号规定为一个16位的0~ -65535之间的整数,其中,0~1023 被预先定义的服务通信占用(如telnet占用端口23,http 占用端口80等),除非需要访问这些特定服务,否则,就应该使用1024 -65535这些端口中的某一个进行通信,以免发生端口冲突。

        当两个程序需要通信时,它们可以通过使用Socket类建立套接字对象并连接在一起(端口号与IP地址的组合得出一个网络套接字)

        通信链路的端点就被称为“套接字”(英文名Socket) 是提供给应用程序的接口

        进行网络编程的类在java.net包

 基于TCP协议的Socket编程

                基于TCP协议的Socket网络通信

                        用来实现双向安全连接网络通信

                Socket通信模型

                        进行网络通信时,Socket需要借助数据流来完成数据的传递工作

Socket网络编程一般可以分成如下步骤进行 

 

网络编程模型:客户端/服务器(C/S)

客户端与服务器端运作过程:

客户端通过输出流将请求信息发送给服务器端
服务器端通过输入流读取客户端的请求信息
服务器端通过输出流将响应信息发送给客户端
客户端通过输入流读取服务器端的响应信息 

package demo01;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;public class Client {public static void main(String[] args) {//创建通信链路的端点客户端套接字Socket socket  = null;OutputStream os = null;InputStream is =null;BufferedReader br =null;try {socket  = new Socket("127.0.0.1", 10088);//获取输出流将数据发送出去os =socket.getOutputStream();String str = "用户名:张三,密码:123456";byte[] bytes=str.getBytes();//通过输出流调用方法将信息发送出去os.write(bytes);System.out.println("我是客户端,我将数据发送完毕");//关闭通道socket.shutdownOutput();//客户端需要通过输入流读取服务器端发送过来的消息is =socket.getInputStream();br = new BufferedReader(new InputStreamReader(is));String result =br.readLine();System.out.println("我是客户端,接收到的服务器端响应信息为:"+result);} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally{try {br.close();is.close();os.close();socket.close();} catch (IOException e) {e.printStackTrace();}}}}

 

package demo01;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) {//创建服务器端套接字ServerSocketServerSocket ss = null;Socket socket =null;InputStream is =null;BufferedReader br =null;OutputStream os =null;try {ss = new ServerSocket(10088);//服务器通过调用侦听方法来获取客户端的请求socket =ss.accept();//通过返回的Socket对象调用方法获取一个输入流来读取客户端发送过来的消息is =socket.getInputStream();//通过 输入流读取客户端发送的消息br = new BufferedReader(new InputStreamReader(is));String str =br.readLine();System.out.println("我这边是服务器:客户端发送给我的数据是:"+str);socket.shutdownInput();//服务器接收客户端消息后,需要给客户端一个响应信息os =socket.getOutputStream();String result = "用户名和密码正确,可以登录";byte[] bytes = result.getBytes();os.write(bytes);System.out.println("给客户端的响应信息发送成功");} catch (IOException e) {e.printStackTrace();}finally{try {os.close();br.close();is.close();socket.close();ss.close();} catch (IOException e) {e.printStackTrace();}}}}

多线程处理多请求

        实现多客户请求

                采用多线程的方式

                一个专门负责监听的应用主服务程序

                一个专门负责处理请求的线程程序

客户端和服务端如何做

客户端跟之前客户端做的事情没有任何改变
客户端通过输出流发送请求信息
客户端通过输入流获取服务器端的响应信息


服务器端做的事情跟之前服务器端做的事情不一样
服务器端循环去侦听客户端的请求,侦听到一个请求就会获取一个Socket类对象,将这个Socket类对象作为参数传递给服务器线程类的有参构造方法里去
服务器线程类通过获取到的Socket类对象去执行原来服务器所做的事情
通过输入流获取客户端的请求信息
通过输出流发送响应信息给客户端

服务器端

package demo03;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) {//创建ServerSocket类对象ServerSocket ss =null;Socket socket =null;try {ss = new ServerSocket(10088);while(true){socket =ss.accept();//将获取到的socket对象传递到线程类中ServerThread st = new ServerThread(socket);st.start();}} catch (IOException e) {e.printStackTrace();}finally{try {ss.close();} catch (IOException e) {e.printStackTrace();}}}}

多个客户端

package demo03;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;public class Client1 {public static void main(String[] args) {//创建通信链路的端点客户端套接字Socket socket  = null;OutputStream os = null;ObjectOutputStream oos =null;InputStream is =null;BufferedReader br =null;try {socket  = new Socket("127.0.0.1", 10088);//获取输出流将数据发送出去os =socket.getOutputStream();//准备Student类对象Student stu = new Student("张三",19);oos = new ObjectOutputStream(os);oos.writeObject(stu);System.out.println("我是客户端1,我将数据发送完毕");//关闭通道socket.shutdownOutput();//客户端需要通过输入流读取服务器端发送过来的消息is =socket.getInputStream();br = new BufferedReader(new InputStreamReader(is));String result =br.readLine();System.out.println("我是客户端1,接收到的服务器端响应信息为:"+result);} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally{try {br.close();is.close();oos.close();os.close();socket.close();} catch (IOException e) {e.printStackTrace();}}}}
package demo03;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;public class Client2 {public static void main(String[] args) {//创建通信链路的端点客户端套接字Socket socket  = null;OutputStream os = null;ObjectOutputStream oos =null;InputStream is =null;BufferedReader br =null;try {socket  = new Socket("127.0.0.1", 10088);//获取输出流将数据发送出去os =socket.getOutputStream();//准备Student类对象Student stu = new Student("李四",22);oos = new ObjectOutputStream(os);oos.writeObject(stu);System.out.println("我是客户端2,我将数据发送完毕");//关闭通道socket.shutdownOutput();//客户端需要通过输入流读取服务器端发送过来的消息is =socket.getInputStream();br = new BufferedReader(new InputStreamReader(is));String result =br.readLine();System.out.println("我是客户端2,接收到的服务器端响应信息为:"+result);} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally{try {br.close();is.close();oos.close();os.close();socket.close();} catch (IOException e) {e.printStackTrace();}}}}

 

package demo03;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;public class Client3 {public static void main(String[] args) {//创建通信链路的端点客户端套接字Socket socket  = null;OutputStream os = null;ObjectOutputStream oos =null;InputStream is =null;BufferedReader br =null;try {socket  = new Socket("127.0.0.1", 10088);//获取输出流将数据发送出去os =socket.getOutputStream();//准备Student类对象Student stu = new Student("如花",16);oos = new ObjectOutputStream(os);oos.writeObject(stu);System.out.println("我是客户端3,我将数据发送完毕");//关闭通道socket.shutdownOutput();//客户端需要通过输入流读取服务器端发送过来的消息is =socket.getInputStream();br = new BufferedReader(new InputStreamReader(is));String result =br.readLine();System.out.println("我是客户端3,接收到的服务器端响应信息为:"+result);} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally{try {br.close();is.close();oos.close();os.close();socket.close();} catch (IOException e) {e.printStackTrace();}}}}

UDP数据报

        套接字是基于TCP协议的网络通信,即客户端程序和服务器端程序是有 连接的,双方的信息是通过程序中的输入、输出流来交互的,使得接收方收到信息的顺序和发送方发送信息的顺序完全相同,就像生活中双方使用电话进行信息交互一样。

        本节介绍Java中基于UDP (用户数据报协议)协议的网络信息传输方式。基于UDP的通信和基于TCP的通信不同,基于UDP的信息传递更快,但不提供可靠性保证。也就是说,数据在传输时,用户无法知道数据能否正确到达目的地主机,也不能确定数据到达目的地的顺序是否和发送的顺序相同。可以把UDP通信比作生活中的邮递信件,我们不能肯定所发的信件就一定能够到达目的地,也不能肯定到达的顺序是发出时的顺序,可能因为某种原因导致后发出的先到达。既然UDP是一种不可靠的协议,为什么还要使用它呢?如果要求数据必须绝对准确地到达目的地,显然不能选择UDP协议来通信。但有时候人们需要较快速地传输信息,并能容忍小的错误,就可以考虑使用UDP协议。

        基于UDP通信的基本模式是:

                将数据打包(好比将信件装入信封一-样),称为数据包,然后将数据包发往目的地。

                接收发来的数据包(好比接收信封一样),然后查看数据包中的内容。

基于UDP协议的Socket编程 

        基于UDP协议的Socket网络编程步骤

                利用 DatagramPacket 对象封装数据包

                利用 DatagramSocket 发送数据包

                利用 DatagramSocket 接收数据包

                利用 DatagramPacket 处理数据包

package demo04;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketAddress;
import java.net.SocketException;/*** 服务器端* */
public class LoginServer {public static void main(String[] args) {byte[] infos=new byte[1024];DatagramPacket dp=new DatagramPacket(infos, infos.length);DatagramSocket socket=null;try {socket=new DatagramSocket(5000);//接收客户端的数据包,并将信息封装在dp中socket.receive(dp);//构建一个字符串String info=new String(dp.getData(),0,dp.getData().length);System.out.println("客户端说:"+info);//给客户端一个响应String reply="您好,我在,请说!";//客户端的地址SocketAddress sa=dp.getSocketAddress();//打一个包裹DatagramPacket dp1=new DatagramPacket(reply.getBytes(),0,reply.getBytes().length,sa);//将包裹寄走socket.send(dp1);} catch (SocketException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally{socket.close();}}
}

 

package demo04;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;/** 客户端* */
public class LoginClient {public static void main(String[] args) {String info="您好,我想咨询一个问题!";byte[] infos=info.getBytes();DatagramSocket socket=null;try {InetAddress ia=InetAddress.getByName("localhost");//构建客户端要发送的数据包对象DatagramPacket dp=new DatagramPacket(infos, infos.length,ia,5000);//客户端需要一个DatagramSocket对象socket=new DatagramSocket();//通过DatagramSocket对象发送数据包到服务器socket.send(dp);//接收服务器的响应byte[] replys=new byte[1024];DatagramPacket dp1=new DatagramPacket(replys, replys.length);socket.receive(dp1);String reply=new String(dp1.getData(),0,dp1.getData().length);System.out.println("服务器回应:"+reply);} catch (UnknownHostException e) {e.printStackTrace();} catch (SocketException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally{//释放资源socket.close();}}
}

 TCP与UDP的主要区别:

TCP

UDP

是否连接

面向连接

面向非连接

传输可靠性

可靠

不可靠

速度

这篇关于网络编程及套接字的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/605155

相关文章

C#反射编程之GetConstructor()方法解读

《C#反射编程之GetConstructor()方法解读》C#中Type类的GetConstructor()方法用于获取指定类型的构造函数,该方法有多个重载版本,可以根据不同的参数获取不同特性的构造函... 目录C# GetConstructor()方法有4个重载以GetConstructor(Type[]

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

poj 3181 网络流,建图。

题意: 农夫约翰为他的牛准备了F种食物和D种饮料。 每头牛都有各自喜欢的食物和饮料,而每种食物和饮料都只能分配给一头牛。 问最多能有多少头牛可以同时得到喜欢的食物和饮料。 解析: 由于要同时得到喜欢的食物和饮料,所以网络流建图的时候要把牛拆点了。 如下建图: s -> 食物 -> 牛1 -> 牛2 -> 饮料 -> t 所以分配一下点: s  =  0, 牛1= 1~

poj 3068 有流量限制的最小费用网络流

题意: m条有向边连接了n个仓库,每条边都有一定费用。 将两种危险品从0运到n-1,除了起点和终点外,危险品不能放在一起,也不能走相同的路径。 求最小的费用是多少。 解析: 抽象出一个源点s一个汇点t,源点与0相连,费用为0,容量为2。 汇点与n - 1相连,费用为0,容量为2。 每条边之间也相连,费用为每条边的费用,容量为1。 建图完毕之后,求一条流量为2的最小费用流就行了

poj 2112 网络流+二分

题意: k台挤奶机,c头牛,每台挤奶机可以挤m头牛。 现在给出每只牛到挤奶机的距离矩阵,求最小化牛的最大路程。 解析: 最大值最小化,最小值最大化,用二分来做。 先求出两点之间的最短距离。 然后二分匹配牛到挤奶机的最大路程,匹配中的判断是在这个最大路程下,是否牛的数量达到c只。 如何求牛的数量呢,用网络流来做。 从源点到牛引一条容量为1的边,然后挤奶机到汇点引一条容量为m的边

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

Go Playground 在线编程环境

For all examples in this and the next chapter, we will use Go Playground. Go Playground represents a web service that can run programs written in Go. It can be opened in a web browser using the follow

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念