端午节学习<网络编程套接字socket>贼cool好吧

简介: 端午节学习<网络编程套接字socket>贼cool好吧

本章要点

学会socket api原理

熟悉TCP和UDP服务器客户端的编写!

概念

Socket套接字,是由系统提供用于网络通信的技术,是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程!


网络编程套接字,是操作系统给应用程序提供的一组API(socket API)!

image.png


socket原意插座!

是传输层和应用层通信的桥梁!

我们调用操作系统的Socket的方法就可通信到传输层!

而我们知道传输层的协议有两种TCP/UDP!

所以socket也提供了两组API用于不同协议点网络编程!


TCP/UDP区别

由于TCP/UDP两组协议相差较大!因而socket下对应的API也差很多!

我们再来介绍一下TCP/UDP协议的特点!

image.png

我们分别介绍一下上述的特点是什么意思!

有连接

有连接就是相当于接电话,需要接通后,才能进行消息传递,不想微信/QQ不要接通就可以发消息!

可靠传输

可靠传输就是我们知道我们当前传输的数据对方是否收到了!就类型于钉钉和淘宝的已读功能!如果我们不知道对方是否收到了,那就是不可靠传输!

这里的可靠并不是传统意义的可靠(和数据是否丢失或者盗窃并么有关系)!

面向字节流

面向字节流传输就是,以字节的为单位进行传输,而面向数据报是以数据报为单位进行传输,一个数据报可能为多个字节,只能传输单位个数据报!


全双工

全双工就是一条链路,双向通信,半双工,就是一条链路,单向通信!


UDP数据报套接字编程

我们先来了解一下UDP协议在socket对应的API~

我们进行网络编程需要用到的类都在java.net包下!


image.png

我们UDP socket 编程主要涉及到下面来个类:

image.png

DatagramPacket

DatagramSocket

我们来学习下这两个类中的一些重要方法:

DatagramPacket 该类表示数据报包


数据报包用于实现无连接分组传送服务。 仅基于该数据包中包含的信息,每个消息从一台机器路由到另一台机器。 从一台机器发送到另一台机器的多个分组可能会有不同的路由,并且可能以任何顺序到达。 包传送不能保证。


UDP网络编程等下可能要用到的方法:


构造方法:

image.png

通过上述的构造方法我们可以创建不同类型的数据报,有用于接收数据的数据报,还有进行发送数据的数据报!


接收数据的数据报:


DatagramPacket(byte[] buf, int length)

构造一个 DatagramPacket用于接收长度的数据包 length 。

DatagramPacket(byte[] buf, int offset, int length)

构造一个 DatagramPacket用于接收长度的分组 length ,指定偏移到缓冲器中。

上面的两种构造方式都是用于接收数据!相当于一个已经设置好容量的空盘子!

buf字节数组,确定字节容量!

length 可以存放多大的字节长度

offset从偏移量位置开始存储


发送数据的数据报


DatagramPacket(byte[] buf, int length, InetAddress address, int port)

构造用于发送长度的分组的数据报包 length指定主机上到指定的端口号。


DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)

构造用于发送长度的分组数据报包 length具有偏移 ioffset指定主机上到指定的端口号。


DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)

构造用于发送长度的分组数据报包 length具有偏移 ioffset指定主机上到指定的端口号。


DatagramPacket(byte[] buf, int length, SocketAddress address)

构造用于发送长度的分组的数据报包 length指定主机上到指定的端口号。


可以看到用于发送数据报的构造方法,要传入,IP和port端口号等信息才知道这个数据报该发给那个客户端!

InetAddress IP地址

port 端口号

SocketAddress:包含了IP和端口号


DatagramSocket 此类表示用于发送和接收数据报数据包的套接字。


数据报套接字是分组传送服务的发送或接收点。 在数据报套接字上发送或接收的每个数据包都被单独寻址和路由。 从一个机器发送到另一个机器的多个分组可以不同地路由,并且可以以任何顺序到达。


构造方法

image.png

DatagramSocket()

构造数据报套接字并将其绑定到本地主机上的任何可用端口。

DatagramSocket(DatagramSocketImpl impl)

使用指定的DatagramSocketImpl创建一个未绑定的数据报套接字。

DatagramSocket(int port)

构造数据报套接字并将其绑定到本地主机上的指定端口。

DatagramSocket(int port, InetAddress laddr)

创建一个数据报套接字,绑定到指定的本地地址。

DatagramSocket(SocketAddress bindaddr)

创建一个数据报套接字,绑定到指定的本地套接字地址。

我们可以传入IP地址和端口号,让该服务器或者客户端绑定该IP或者该端口号!

也可以无参,由系统分配端口号!


上面这两个类中还有许多常用方法,我们使用到的时候再介绍!


UDP数据报套接字编程案例

回显服务客户端和服务器

我们通过UDP socket 实现一个回显服务的服务器和客户端,就是客户端给服务器发信息,服务器会转发刚刚发送的信息给客户端!

通过这个案例,可以学习UDP网络编程的流程!


//回显服务器代码
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpEchoServer {
    //1.源端口 服务器的端口号 需要自己设置
    //2.源IP 服务器主机的IP
    //3.目的端口 客户端的端口号 服务器接收的数据报中有
    //4.目的IP 客户端IP 服务器接收的数据报中!
    //5.协议类型 UDP
    //编程前提 创建socket实例 用于操作系统中的socket api
     DatagramSocket socket = null;
    public UdpEchoServer(int port) throws SocketException { //设置服务器的端口号
        socket = new DatagramSocket(port);
    }
    //启动服务器
    public void start() throws IOException {
        System.out.println("启动服务器!");
        //UDP不需要建立连接,直接接收请求即可!
        while (true){
            //为了接收数据 创建了一个指定空间大小的空数据报!
            DatagramPacket requestPacket = new  DatagramPacket(new byte[1024],1024);
            socket.receive(requestPacket);//输出型参数 //request 就接收到了数据!
            //获取请求,将数据报转化成字符串!
            //指定获取数据的起始位置和长度还有编码格式
            String request = new String(requestPacket.getData(),0,requestPacket.getLength(),"UTF-8");
            //根据请求计算响应
            String response = process(request);
            //将响应封装成数据报
            //转化成字节数组,字节大小,目的端口和地址getSocktAddress!
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
            socket.send(responsePacket);
            //将客户端的ip 端口 请求 响应 打印
            System.out.printf("[%s,%d] req:%s res:%s\n",requestPacket.getAddress(),requestPacket.getPort(),request,response);
        }
    }
    public String  process(String request) {
        //回显服务,直接返回请求
        return  request;
    }
    public static void main(String[] args) throws IOException {
        UdpEchoServer udpEchoServer = new UdpEchoServer(9090); //设置服务器端口 9090
        udpEchoServer.start(); //启动服务器!
    }
}
//回显客户端代码
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UdpEchoClient {
    //1.源IP 客户端本机IP
    //2.源端口 客户端端口 可以由系统随机分配
    //3.目的IP 服务器IP
    //4.目的端口 服务器端口
    //5.协议类型 UDP
    DatagramSocket socket= null;
    String serverIp =null;
    int serverPort = 0;
    public UdpEchoClient(String serverIp,int serverPort) throws SocketException {
        //服务器不需要指定端口,系统分配!
        socket = new DatagramSocket();
        this.serverIp = serverIp;
        this.serverPort = serverPort;
    }
    //启动客户端
    public void start() throws IOException {
        System.out.println("启动客户端");
        Scanner scanner = new Scanner(System.in);
        while(true){
            //写请求 从控制台输入字符!
            System.out.print("->");
            String request = scanner.nextLine();
            //将请求封装成数据报
            //这里需要将目的IP和端口传入! 并且需要调用InetAddress.getByName(serverIp)传入目的IP
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(serverIp),serverPort);
            //发送请求给客户端
            socket.send(requestPacket);
            //接收请求
            //给出接收请求的空数据报
            DatagramPacket responsePacket = new DatagramPacket(new byte[1024],1024);
            socket.receive(responsePacket);
            //将收到的数据报转化成字符串显示
            //起始位置,长度,编码方式
            String response = new String(responsePacket.getData(),0,responsePacket.getLength(),"UTF-8");
            //输出响应
            System.out.println("req:"+request+" res:"+response);
        }
    }
    public static void main(String[] args) throws IOException {
        //这里传入的是服务器的IP和端口号
        UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1",9090);
        //启动服务器
        udpEchoClient.start();
    }
}

启动服务器:

image.png

启动客户端:

image.png

我们需要先启动服务器,然后再启动客户端,因为服务器是被动接收的一方,如果客户端没有和服务器发送信息,那么服务器就会一直阻塞在 socket.receive(requestPacket)等待客户端!

image.png

服务器接收到端口号为57266客户端的请求,发送了响应!

image.png

而客户端也接收到了服务器发送的响应,实现了回显服务!


我们知道一个服务器程序一般都有多个客户端访问!

如果想要有其他的客户端访问,该如何做呢!

image.png

当我们再次启动客户端程序,会弹出让我们先关闭该程序的窗口!

这样就只能运行一个客户端…


当我们√上Allow parallel run就可以同时运行多个实例!

image.png


此时我们就有多个客户端了!

image.png

服务器也连接了多个客户端!

这就是实现了1对多!


字典服务客户端服务器

刚刚的案例,显然没有一点技术,我可改进一下响应,写一个字典服务的服务器,支持中英翻译!


//翻译服务服务器
import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
public class UdpDictServer extends UdpEchoServer{
    private HashMap<String,String> dict = new HashMap<>();
    public UdpDictServer(int port) throws SocketException {
        super(port);
        dict.put("cat","小猫");
        dict.put("dog","小狗");
        dict.put("pig","小猪");
        dict.put("child","小孩");
    }
    @Override
    public String process(String request) {
        //返回翻译!
        return dict.getOrDefault(request,"暂且不会");
    }
    public static void main(String[] args) throws IOException {
        UdpDictServer udpDictServer =new UdpDictServer(9090);
        udpDictServer.start();
    }
}

我们客户端并不用改变,访问该服务器就可以实现翻译的效果!

image.png


TCP流套接字编程

我们知道TCP是有连接的!

所以我们需要先对客户端建立连接!

我们来学习一下TCP协议对应的Socket API!


我们先来学习两个类:

通过这两个类我们就可以对TCP协议网络编程!


这两个类也在java.net包下!

image.png

ServerSocket

这个类实现了服务器套接字。

服务器套接字等待通过网络进入的请求。 它根据该请求执行一些操作,然后可能将结果返回给请求者。

服务器套接字的实际工作由SocketImpl类的实例执行。 应用程序可以更改创建套接字实现的套接字工厂,以配置自己创建适合本地防火墙的套接字!

构造方法:

image.png


ServerSocket()

创建未绑定的服务器套接字。

ServerSocket(int port)

创建绑定到指定端口的服务器套接字。

ServerSocket(int port, int backlog)

创建服务器套接字并将其绑定到指定的本地端口号,并指定了积压。

ServerSocket(int port, int backlog, InetAddress bindAddr)

创建一个具有指定端口的服务器,侦听backlog和本地IP地址绑定。

我们主要用到的是第二个构造方法!我们的服务器一般都需要绑定端口号,便于客户端访问!

这个类一般用于服务器程序!


需要用到的方法

image.pngimage.png


Socket accept()

倾听要连接到此套接字并接受它!

通过这个方法,我们就可以与客户端建立连接!

返回的Socket对象,我们后面的操作就对socket对象进行就好了!

ServerSocket对象就完成了他的任务和使命了!


就好比之前的电话接线员,连接后就和他没有关系了!剩下的就交个两个打电话的人了!这里的也是剩下的就交给socket对象就好了!


用通俗的话讲就是,这里的ServerSocket就做了一件事情,通过网络请求,与客户端建立连接,执行完后就将结果返回给请求者!


Socket

该类实现客户端套接字(也称为“套接字”)。 套接字是两台机器之间通讯的端点。

套接字的实际工作由SocketImpl类的实例执行。 应用程序通过更改创建套接字实现的套接字工厂,可以配置自己创建适合本地防火墙的套接字。

这里的Socket对象就相当于接电话的两个人,下面的通讯操作,主要通过这个类来实现!


构造方法

image.png


Socket()

创建一个未连接的套接字,并使用系统默认类型的SocketImpl。

Socket(InetAddress address, int port)

创建流套接字并将其连接到指定IP地址的指定端口号。

我们主要学习这两个构造方法!

第一个无参构造,一般用于服务器!当ServerSocket对象调用accept方法后就可以用这个对象接收!因为这个socket对象是来自客户端,所有已经有了端口号!


而第二个构造方法一般用于创建服务器socket!

注意:

这里的address 和port并不是像UDP一样设置直接的端口号,而是连接到这个IP和端口号的服务器!


需要用到的方法


void close()

关闭此套接字。

InetAddress getInetAddress()

返回套接字所连接的地址。

InetAddress getLocalAddress()

获取套接字所绑定的本地地址。

这里一个是连接的服务器地址,一个是自己的地址!


int getLocalPort()

返回此套接字绑定到的本地端口号。

InputStream getInputStream()

返回此套接字的输入流。

OutputStream getOutputStream()

返回此套接字的输出流。

我们上面的这两个方法就实现了TCP面向字节流!


通过操作上面的两个对象就可以实现通信,输入和输出了!


TCP面向字节流网络编程案例

回显服务客户端服务器

//回显服务服务器
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class TcpEchoServer {
    //1.ServerSocket 只负责建立连接!
    ServerSocket serverSocket = null;
    public TcpEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动!");
        while(true){
            //因为TCP是有连接的,我们要先建立连接(接电话)
            //ServerSocket只做了一件事情,调用accept方法建立连接
            //我们就得到了socketClient客户!!!
            //后面就只需要针对socketClient进行操作即可!
            //如果没有客户端连接,accept就会阻塞!
            Socket socketClient = serverSocket.accept();
            processConnection(socketClient);
        }
    }
    public void processConnection(Socket socketClient) {
        //TCP面向字节流,所以直接通过文件操作,便可以将数据读写!
        try(InputStream inputStream = socketClient.getInputStream()) {
            //调用getInputStrem方法获取到请求,用输入字节流接收!
            try(OutputStream outputStream = socketClient.getOutputStream()){
                //调用getOutStrem方法,用于输出应答!
                //通过scanner读取请求更便利!
                Scanner scanner = new Scanner(inputStream);
                //循环处理每一个请求,返回对应响应!
                while(true){
                    if(!scanner.hasNext()){
                        System.out.printf("[客户端IP:%s,port:%d] 退出连接\n",socketClient.getInetAddress(),socketClient.getPort());
                        break;
                    }
                    //获取到请求
                    String request = scanner.next();
                    //根据请求给出应答
                    String response = process(request);
                    //把这个响应给客户端!
                    //通过printwiter包裹OutputSteam!
                    PrintWriter printWriter = new PrintWriter(outputStream);
                    //将请求字符串写入到输出流中!
                    printWriter.println(response);
                    printWriter.flush();//刷新缓冲器,让客户端立即获取到响应!
                    System.out.printf("[客户端IP:%s,port:%d] req:%s,res:%s\n",socketClient.getInetAddress(),socketClient.getPort(),request,response);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //关闭资源!
                socketClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public String process(String request) {
        //回显
        return request;
    }
    public static void main(String[] args) throws IOException {
        TcpEchoServer tcpEchoServer = new TcpEchoServer(9090);
        tcpEchoServer.start();
    }
}
//回显服务客户端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class TcpEchoClient {
    private Socket socket = null;
    public TcpEchoClient(String serverIp,int serverPort) throws IOException {
        //客户端
        //这里的IP和端口是服务器的,并且这里传入IP和port表示与这个服务器建立连接!
        socket = new Socket(serverIp,serverPort);
    }
    public void start(){
        System.out.println("和服务器连接成功!");
        Scanner scanner = new Scanner(System.in);
        try(InputStream inputStream = socket.getInputStream()){
            try(OutputStream outputStream = socket.getOutputStream()){
                while(true){
                    //1.从控制台读取请求
                    System.out.print("->");
                    String request = scanner.next();
                    //2.构造请求并发送给服务器
                    PrintWriter printWriter = new PrintWriter(outputStream);
                    printWriter.println(request);
                    printWriter.flush();
                    //3.读取响应
                    Scanner scannerResponse = new Scanner(inputStream);
                    String response = scannerResponse.next();
                    //把结果打印到控制台!
                    System.out.printf("req:%s,res:%s\n",request,response);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //关闭资源
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) throws IOException {
      TcpEchoClient tcpEchoClient = new TcpEchoClient("127.0.0.1",9090);
      tcpEchoClient.start();
    }
}

启动服务器:

image.png

启动客户端:

image.png


可以看到,这里我们也实现了回显服务!


当我们多开几个客户端试试!

image.png


可以看到客户端并没有收到应答,服务器也没和客户端建立连接!


因为,我们的ServerSocket对象,调用了accept后就一直在循环中,如果当前客户端不和服务器断开连接的话,就不会和其他客户端建立连接了!

image.png

我们如何才能实现多客户端呢?


我们回顾之前的对线程操作!我们可以有多个线程同时对多个客户端建立连接!!!

那我们进行升级一下变成多进程版本的服务器!


//多线程版本服务器
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class TcpThreadEchoServer{
    //1.ServerSocket 只负责建立连接!
    ServerSocket serverSocket = null;
    public TcpThreadEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动!");
        while(true){
            //因为TCP是有连接的,我们要先建立连接(接电话)
            //ServerSocket只做了一件事情,调用accept方法建立连接
            //我们就得到了socketClient客户!!!
            //后面就只需要针对socketClient进行操作即可!
            //如果没有客户端连接,accept就会阻塞!
            Thread thread = new Thread(()->{
                Socket socketClient = null;
                try {
                    socketClient = serverSocket.accept();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                processConnection(socketClient);
            });
           thread.start();
        }
    }
    public void processConnection(Socket socketClient) {
        //TCP面向字节流,所以直接通过文件操作,便可以将数据读写!
        try(InputStream inputStream = socketClient.getInputStream()) {
            //调用getInputStrem方法获取到请求,用输入字节流接收!
            try(OutputStream outputStream = socketClient.getOutputStream()){
                //调用getOutStrem方法,用于输出应答!
                //通过scanner读取请求更便利!
                Scanner scanner = new Scanner(inputStream);
                //循环处理每一个请求,返回对应响应!
                while(true){
                    if(!scanner.hasNext()){
                        System.out.printf("[客户端IP:%s,port:%d] 退出连接\n",socketClient.getInetAddress(),socketClient.getPort());
                        break;
                    }
                    //获取到请求
                    String request = scanner.next();
                    //根据请求给出应答
                    String response = process(request);
                    //把这个响应给客户端!
                    //通过printwiter包裹OutputSteam!
                    PrintWriter printWriter = new PrintWriter(outputStream);
                    //将请求字符串写入到输出流中!
                    printWriter.println(response);
                    printWriter.flush();//刷新缓冲器,让客户端立即获取到响应!
                    System.out.printf("[客户端IP:%s,port:%d] req:%s,res:%s\n",socketClient.getInetAddress(),socketClient.getPort(),request,response);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //关闭资源!
                socketClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public String process(String request) {
        //回显
        return request;
    }
    public static void main(String[] args) throws IOException {
        TcpThreadEchoServer tcpThreadEchoServer = new TcpThreadEchoServer(9090);
        tcpThreadEchoServer.start();
    }
}

image.png

我们只更改了一点代码就实现了多个客户端!


我们来学习了线程池,我们在更改成线程池版本!


//线程池版本服务器
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TcpThreadPoolEchoServer {
    //1.ServerSocket 只负责建立连接!
    ServerSocket serverSocket = null;
    public TcpThreadPoolEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动!");
        ExecutorService pool = Executors.newCachedThreadPool();
        while(true){
            //因为TCP是有连接的,我们要先建立连接(接电话)
            //ServerSocket只做了一件事情,调用accept方法建立连接
            //我们就得到了socketClient客户!!!
            //后面就只需要针对socketClient进行操作即可!
            //如果没有客户端连接,accept就会阻塞!
            //线程池版本!
            Socket socketClient = serverSocket.accept();
            pool.submit(new Runnable() {
                @Override
                public void run() {
                }
            });
            processConnection(socketClient);
        }
    }
    public void processConnection(Socket socketClient) {
        //TCP面向字节流,所以直接通过文件操作,便可以将数据读写!
        try(InputStream inputStream = socketClient.getInputStream()) {
            //调用getInputStrem方法获取到请求,用输入字节流接收!
            try(OutputStream outputStream = socketClient.getOutputStream()){
                //调用getOutStrem方法,用于输出应答!
                //通过scanner读取请求更便利!
                Scanner scanner = new Scanner(inputStream);
                //循环处理每一个请求,返回对应响应!
                while(true){
                    if(!scanner.hasNext()){
                        System.out.printf("[客户端IP:%s,port:%d] 退出连接\n",socketClient.getInetAddress(),socketClient.getPort());
                        break;
                    }
                    //获取到请求
                    String request = scanner.next();
                    //根据请求给出应答
                    String response = process(request);
                    //把这个响应给客户端!
                    //通过printwiter包裹OutputSteam!
                    PrintWriter printWriter = new PrintWriter(outputStream);
                    //将请求字符串写入到输出流中!
                    printWriter.println(response);
                    printWriter.flush();//刷新缓冲器,让客户端立即获取到响应!
                    System.out.printf("[客户端IP:%s,port:%d] req:%s,res:%s\n",socketClient.getInetAddress(),socketClient.getPort(),request,response);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //关闭资源!
                socketClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public String process(String request) {
        //回显
        return request;
    }
    public static void main(String[] args) throws IOException {
        TcpThreadPoolEchoServer tcpThreadPoolEchoServer = new TcpThreadPoolEchoServer(9090);
        tcpThreadPoolEchoServer.start();
    }
}

我们对TCP和UDP socket API网络编程的学习就到此为止,还有其他的内容,我们下次学习!

目录
相关文章
|
3天前
|
分布式计算 网络协议 Python
Python网络编程:socket编程
Socket 编程是网络编程的重要部分,主要用于在不同计算机之间进行通信。Python 提供了一个非常强大的 socket 库,使得网络编程变得简单和灵活。本篇博文将详细介绍 Python 的 socket 编程,包括基础概念、核心组件、常用功能,并附上一个综合的示例及其运行结果。
|
3天前
|
网络协议
详解VXLAN网络中报文是如何转发的?值得收藏学习!
详解VXLAN网络中报文是如何转发的?值得收藏学习!
详解VXLAN网络中报文是如何转发的?值得收藏学习!
|
16天前
|
机器学习/深度学习 人工智能 TensorFlow
神经网络不再是黑魔法!Python带你一步步拆解,让AI学习看得见
【8月更文挑战第3天】神经网络,曾被视为难以触及的黑魔法,现已在Python的助力下变得平易近人。以TensorFlow或PyTorch为“魔法杖”,仅需几行Python代码即可构建强大的AI模型。从零开始,我们将教导AI识别手写数字,利用经典的MNIST数据集。通过数据加载、预处理至模型训练与评估,每个步骤都如精心编排的舞蹈般清晰可见。随着训练深入,AI逐渐学会辨认每个数字,其学习过程直观展现。这不仅揭示了神经网络的奥秘,更证明了任何人都能借助Python创造AI奇迹,共同探索未来的无限可能。
23 2
|
16天前
|
机器学习/深度学习 算法 网络架构
神经网络架构殊途同归?ICML 2024论文:模型不同,但学习内容相同
【8月更文挑战第3天】《神经语言模型的缩放定律》由OpenAI研究人员完成并在ICML 2024发表。研究揭示了模型性能与大小、数据集及计算资源间的幂律关系,表明增大任一资源均可预测地提升性能。此外,论文指出模型宽度与深度对性能影响较小,较大模型在更多数据上训练能更好泛化,且能高效利用计算资源。研究提供了训练策略建议,对于神经语言模型优化意义重大,但也存在局限性,需进一步探索。论文链接:[https://arxiv.org/abs/2001.08361]。
17 1
|
25天前
|
网络协议 开发者 Python
网络编程小白秒变大咖!Python Socket基础与进阶教程,轻松上手无压力!
【7月更文挑战第25天】在网络技术快速发展的背景下, Python因其简洁的语法和强大的库支持成为学习网络编程的理想选择。
42 5
|
24天前
|
网络协议 程序员 视频直播
|
2天前
|
运维 网络协议 API
入门网络,少不了这份详细的网络基础学习指南!
入门网络,少不了这份详细的网络基础学习指南!
|
23天前
|
网络协议 Python
告别网络编程迷雾!Python Socket编程基础与实战,让你秒变网络达人!
【7月更文挑战第27天】在网络编程的广阔天地中,Socket编程常被视为一道难关。但用Python这把钥匙,我们可以轻松入门。Socket作为网络通信的基石,在Python中通过`socket`模块封装了底层细节,简化了开发过程。以下是一个基本的TCP服务器与客户端的示例,展示了如何建立连接、收发数据及关闭连接。为了应对实际场景中的并发需求,我们还可以借助多线程技术来提升服务器处理能力。掌握了这些基础知识后,你将逐步揭开网络编程的神秘面纱,踏上编程高手之路!
23 0
|
23天前
|
网络协议 Python
深度剖析Python Socket:从入门到精通,网络编程不再是难题!
【7月更文挑战第27天】在Python中,Socket编程是网络通信的核心。本文从Socket基础概念入手,介绍其作为网络通信端点的作用,并区分TCP(面向连接)与UDP(无连接)。通过示例代码展示如何创建TCP服务器及客户端:服务器监听12345端口,接收并回显客户端消息;客户端则连接服务器并发送消息,接收服务器回应。代码涵盖socket创建、连接管理及数据收发等关键步骤,并强调异常处理与数据编码的重要性。掌握这些基础知识,即可轻松开展网络编程项目。
39 0
|
25天前
|
网络协议 开发者 Python
深度探索Python Socket编程:从理论到实践,进阶篇带你领略网络编程的魅力!
【7月更文挑战第25天】在网络编程中, Python Socket编程因灵活性强而广受青睐。本文采用问答形式深入探讨其进阶技巧。**问题一**: Socket编程基于TCP/IP,通过创建Socket对象实现通信,支持客户端和服务器间的数据交换。**问题二**: 提升并发处理能力的方法包括多线程(适用于I/O密集型任务)、多进程(绕过GIL限制)和异步IO(asyncio)。**问题三**: 提供了一个使用asyncio库实现的异步Socket服务器示例,展示如何接收及响应客户端消息。通过这些内容,希望能激发读者对网络编程的兴趣并引导进一步探索。
21 4