精华内容
下载资源
问答
  • 【网络编程3】Java组播套接字

    千次阅读 2016-06-14 23:21:40
    这篇博文是本文学习《Java网络程序设计》书中第5章中组播套接字的学习总结。所有源代码都在文章后面我的github链接代码中。 前面两篇博客介绍了发送端程序线程发送单一的消息(通过流套接字和数据报套接字)给唯一...

    这篇博文是本文学习《Java网络程序设计》书中第5章中组播套接字的学习总结。所有源代码都在文章后面我的github链接代码中。
    ——惠州学院13网络工程 吴成兵 20160612

    目录 1

    一 组播套接字概述

    前面两篇博客介绍了发送端程序线程发送单一的消息(通过流套接字和数据报套接字)给唯一的接收端程序,这种行为被称为单点传送(unicasting)。如果发送端程序要将同一信息发送给多个接收端,那么发送端程序和接收端程序可以利用多点传送(multicasting)方式进行通信。多点传送就是发送端程序对专用的多点传送组的IP地址和端口发送一系统自寻址数据包,通过加入操作IP地址被多点传送Socket注册,通过这个点,客户程序可以接收发送给组的自寻址包(同样接收端程序也可以给这个组发送自寻址包),一旦客户程序读完所有要读的自寻址数据包,那么可以通过离开组操作多点传送组。
    组播套接字通信流程
      DatagramSocket只允许数据报包发送给指定的目的地址,而MulticastSocket则可以将数据报包以广播方式发送到数量不等的多个接收端。若要使用多点广播,则需要让一个数据报包标有组目标主机地址,当数据报包发出后,整个组的所有主机都能收到该数据报包。IP多点广播(或多点发送)实现了将单一信息发送到多个接收端的广播,其思想是设置一个特殊网络地址作为多点广播地址,每一个要收到多点广播地址都被看做一个组,接收端需要接收广播信息时,加入到组即可,发送端则向每组发送数据报包。IP协议为多点广播提供了这批特殊的IP地址,这些IP地址的范围是224.0.0.0~239.255.255.255。

    二 MulticastSocket ##

    public class MulticastSocket extends DatagramSocket 
    

    MulticastSocket是DatagramSocket的一个子类,扩展了DatagramSocket类的一些方法,就有权访问DatagramSocket的方法。

    2.1 MulticastSocket构造方法

    • public MulticastSocket(int port) throws IOException :使用本机默认地址、指定端口来创建一个MulticastSocket对象,用于接收端或发送端。
    • public MulticastSocket() throws IOException :使用本机默认地址、随机端口来创建一个MulticastSocket对象,用于发送端。(同上面构造方法port=0的情况)
    • public MulticastSocket(SocketAddress bindaddr) throws IOException :使用本机指定地址、指定端口来创建一个MulticastSocket对象。

    2.2MulticastSocket常用方法

    • public void joinGroup(InetAddress mcastaddr) throws IOException :建立了MultiSocket对象后,要发送或接收组播包,必须用joinGroup方法加入一个组播组。
    • public void leaveGroup(InetAddress mcastaddr) throws IOException :如果不想接收组播包了,就调用leaveGroup方法。程序就发信息到组播路由器,通知它停止向此用户发送数据。
    • public void send(DatagramPacket p) throws IOException :和DatagramSocket发送数据的方法相似。
    • public synchronized void receive(DatagramPacket p) throws IOException :和DatagramSocket接收数据的方法相似。
      @Deprecated
    • public void send(DatagramPacket p, byte ttl) throws IOException:和DatagramSocket发送数据的方法相似,其中ttl是生存时间,大小在0~255之间。
    • public void setTimeToLive(int ttl) throws IOException :设置套接字发出的组播包中的默认ttl数值。
    • public int getTimeToLive() throws IOException :返回ttl数值。
      MultiSocket比DatagramSocket多了setTimeToLive(int ttl)方法,该ttl参数设置数据报包最多可以跨过多少个网络:
      当ttl为0时,指定数据报包应停留在本地主机
      当ttl为1时,指定数据报包应发送到本地局域网;(默认情况下)
      当ttl为32时,意味着数据报包应发送到本站点的网络上
      当ttl为64时,意味着数据报包应保留在本地区
      当ttl为128时,意味着数据报包应保留在本大洲
      当ttl为255时,意味着数据报包可以发送到所有地方

    三 组播套接字编程

    3.1 使用组播套接字发送数据的过程

    • 调用MulticastSocket()创建一个组播套接字。
    • 创建DatagramPacket数据报。
    • 调用MulticastSocket类的send()方法发送组播包。
    • 关闭组播套接字。
      发送送组播包的代码如下:
    package _5_3组播套接字;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.InetAddress;
    import java.net.MulticastSocket;
    
    public class MCServer {
    
    	public static void main(String[] args) throws IOException {
    
    		System.out.println("Server starting...");
    		MulticastSocket s = new MulticastSocket();
    		InetAddress group = InetAddress.getByName("231.0.0.1");
    		byte[] dummy = new byte[0];
    		DatagramPacket dgp = new DatagramPacket(dummy, 0, group, 10000);
    		for (int i = 0; i < 30000; i++) {
    			byte[] buffer = ("Video line " + i).getBytes();
    			dgp.setData(buffer);
    			dgp.setLength(buffer.length);
    			s.send(dgp);
    		}
    	}
    }
    
    

    ##3.2 使用组播套接字接收数据的过程##

    • 调用MulticastSocket()创建一个组播套接字。
    • 调用MulticastSocket类的joinGroup()方法加入一个组播组。
    • 创建DatagramPacket数据报。
    • 调用MulticastSocket类的receive()方法接收组播包。
    • 调用MulticastSocket类的leaveGroup()方法离开该组播组。
    • 关闭组播套接字。
      接收送组播包的代码如下:
    package _5_3组播套接字;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.InetAddress;
    import java.net.MulticastSocket;
    
    public class MCClient {
    
    	public static void main(String[] args) throws IOException {
    
    		MulticastSocket s = new MulticastSocket(10000);
    		InetAddress group = InetAddress.getByName("231.0.0.1");
    		s.joinGroup(group);
    		for (int i = 0; i < 10; i++) {
    			byte[] buffer = new byte[256];
    			DatagramPacket dgp = new DatagramPacket(buffer, buffer.length);
    			s.receive(dgp);
    			byte[] buffer2 = new byte[dgp.getLength()];
    			System.arraycopy(dgp.getData(), 0, buffer2, 0, dgp.getLength());
    			System.out.println(new String(buffer2));
    		}
    		s.leaveGroup(group);
    		s.close();
    
    	}
    
    }
    
    

    四 组播套接字编程示例

    4.1 组播套接字发送和接收程序

    发送端发送的中文数据要用UTF-8格式,否则接收端将会收到乱码。
    sender
    receiver

    4.1.1 发送端

    package _07实验七_组播编程.MulticastProject2.test;
    
    import java.net.DatagramPacket;  
    import java.net.InetAddress;  
    import java.net.MulticastSocket;  
    import java.util.Date;  
      
    /**
     * Copyright ? 2016 Authors. All rights reserved.
     *
     * FileName: .java
     * @author : Wu_Being <1040003585@qq.com>
     * Date/Time: 2016-6-14/下午08:46:39
     * Description: 组播的服务端 
     */
    public class MulticastSender_UTF8 {  
          
        public static void server() throws Exception{  
            InetAddress group = InetAddress.getByName("239.1.2.3");//组播地址  
            int port = 22363;  
            MulticastSocket mss = null;  
            try {  
                mss = new MulticastSocket(port);  
                mss.joinGroup(group);  
                System.out.println("发数据包启动!(启动时"+new Date()+")");  
                  
                while(true){  
                    String message = "Hello,你的电脑已中毒##"+new Date();  
                    byte[] buffer = message.getBytes();  
                    DatagramPacket dp = new DatagramPacket(buffer, buffer.length,group,port);  
                    mss.send(dp);  
                    System.out.println("发数据("+message+")包给 "+group+":"+port);  
                    Thread.sleep(1);  
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
            }finally{  
                try {  
                    if(mss!=null){  
                        mss.leaveGroup(group);  
                        mss.close();  
                    }  
                } catch (Exception e2) {  
                    // TODO: handle exception  
                }  
            }  
        }  
          
        public static void main(String[] args) throws Exception {  
            server();  
        }  
    }  
    
    

    4.1.2 接收端

    package _07实验七_组播编程.MulticastProject2.test;
    
    import java.net.DatagramPacket;
    import java.net.InetAddress;
    import java.net.MulticastSocket;
    import java.util.Date;
    
    /**
     * 
     * Copyright ? 2016 Authors. All rights reserved.
     *
     * FileName: .java
     * @author : Wu_Being <1040003585@qq.com>
     * Date/Time: 2016-6-14/下午10:16:44
     * Description:
     */
    public class MulticastReceive_UTF8 {
        
        public static void main(String[] args) throws Exception {  
            test();  
        }  
          
        public static void test() throws Exception{  
            InetAddress group = InetAddress.getByName("239.1.2.3");//组播地址  
            int port = 22363;  
           MulticastSocket msr = null;//创建组播套接字  
            try {  
                msr = new MulticastSocket(port);  
                msr.joinGroup(group);//加入连接  
                byte[] buffer = new byte[8192];  
                System.out.println("接收数据包启动!(启动时间: "+new Date()+")");  
                while(true){  
                    //建立一个指定缓冲区大小的数据包  
                    DatagramPacket dp = new DatagramPacket(buffer, buffer.length);  
                    msr.receive(dp);  
                    String s = new String(dp.getData(),0,dp.getLength());  
                    //解码组播数据包  
                    System.out.println("收到"+dp.getSocketAddress()+"数据("+s+")");  
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
            }finally{  
                if(msr!=null){  
                    try {  
                        msr.leaveGroup(group);  
                        msr.close();  
                    } catch (Exception e2) {  
                        // TODO: handle exception  
                    }  
                }  
            }  
        }  
          
     
    }  
    
    

    4.2 组播应用:英汉词典

    broadcastwords

    4.2.1 广播端

    package _5_4组播套接字编程示例._5_4_2组播应用_英汉词典;
    
    
    import java.awt.BorderLayout;
    import java.awt.Button;
    import java.awt.Color;
    import java.awt.FileDialog;
    import java.awt.Frame;
    import java.awt.GridLayout;
    import java.awt.Panel;
    import java.awt.TextArea;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.InetAddress;
    import java.net.MulticastSocket;
    import java.net.UnknownHostException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.Timer;
    
    /**
     *
     * @author geek
     */
    @SuppressWarnings("serial")
    public class BroadCastWord extends Frame implements ActionListener {
        
        int port;
        InetAddress group = null;
        MulticastSocket socket = null;
        Timer time = null;
        FileDialog open = null;
        Button select, startBroadCast, stopBroadCast;
        File file = null;
        String fileDir = null, fileName = null;
        FileReader in = null;
        BufferedReader br = null;
        int token = 0;
        TextArea showPlaying, showPlayed;
        
        public BroadCastWord() {
            super("单词广播系统");
            select = new Button("Select to broadcast file");
            startBroadCast = new Button("start broadcast");
            stopBroadCast = new Button("stop broadcast");
            startBroadCast.addActionListener(this);
            startBroadCast.setEnabled(false);
            select.addActionListener(this);
            stopBroadCast.addActionListener(this);
            stopBroadCast.setEnabled(false);
            time = new Timer(2000, this);
            open = new FileDialog(this, "选择要广播的文件", FileDialog.LOAD);
            showPlaying = new TextArea(10, 10);
            showPlaying.setForeground(Color.blue);
            showPlayed = new TextArea(10, 10);
            Panel north = new Panel();
            north.add(select);
            north.add(startBroadCast);
            north.add(stopBroadCast);
            add(north, BorderLayout.NORTH);
            Panel center = new Panel();
            center.setLayout(new GridLayout(1, 2));
            center.add(showPlaying);
            center.add(showPlayed);
            add(center, BorderLayout.CENTER);
            validate();
            port = 5000;
            try {
                group = InetAddress.getByName("239.255.0.0");
                socket = new MulticastSocket(port);
                socket.setTimeToLive(1);
                socket.joinGroup(group);
            } catch (UnknownHostException ex) {
                Logger.getLogger(Receive.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(Receive.class.getName()).log(Level.SEVERE, null, ex);
            }
            setBounds(100, 50, 360, 380);
            setVisible(true);
            addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
                
            });
        }
        
        public static void main(String[] args) {
            new BroadCastWord();
        }
        
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == select) {
                showPlayed.setText(null);
                open.setVisible(true);
                fileName = open.getFile();
                fileDir = open.getDirectory();
                file = new File(fileDir, fileName);
                try {
                    in = new FileReader(file);
                    br = new BufferedReader(in);
                    startBroadCast.setEnabled(true);
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(BroadCastWord.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else if (e.getSource() == startBroadCast) {
                time.start();
                startBroadCast.setEnabled(false);
                stopBroadCast.setEnabled(true);
            } else if (e.getSource() == time) {
                String s = null;
                try {
                    if (token == -1) {
                        file = new File(fileDir, fileName);
                        in = new FileReader(file);
                        br = new BufferedReader(in);
                    }
                    s = br.readLine();
                    if (s != null) {
                        token = 0;
                        showPlaying.setText("正在广播的内容:\n" + s);
                        showPlayed.append(s + "\n");
                        byte buf[] = s.getBytes();
                        DatagramPacket packet = new DatagramPacket(buf, buf.length, group, port);
                        socket.send(packet);
                    } else {
                        token = -1;
                    }
                } catch (Exception ex) {
                    
                }
                
            } else if (e.getSource()
                    == stopBroadCast) {
                time.stop();
                stopBroadCast.setEnabled(false);
                startBroadCast.setEnabled(true);
            }
        }
        
    }
    
    

    4.2.2 接收端

    package _5_4组播套接字编程示例._5_4_2组播应用_英汉词典;
    
    
    import java.awt.BorderLayout;
    import java.awt.Button;
    import java.awt.Color;
    import java.awt.Frame;
    import java.awt.GridLayout;
    import java.awt.Panel;
    import java.awt.TextArea;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.InetAddress;
    import java.net.MulticastSocket;
    import java.net.UnknownHostException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    /**
     * 
     * Copyright ? 2016 Authors. All rights reserved.
     *
     * FileName: .java
     * @author : Wu_Being <1040003585@qq.com>
     * Date/Time: 2016-6-14/下午10:51:10
     * Description:
     */
    @SuppressWarnings("serial")
    public class Receive extends Frame implements Runnable, ActionListener {
    
        int port;
        InetAddress group = null;
        MulticastSocket socket = null;
        Button startRece, stopRece;
        Thread thread = null;
        TextArea showReceiving, showReceived;
        boolean stoped = false;
    
        public Receive() {
            super("定时接收信息");
            thread = new Thread(this);
            startRece = new Button("start receive");
            stopRece = new Button("stop receive");
            startRece.addActionListener(this);
            stopRece.addActionListener(this);
            showReceiving = new TextArea(10, 10);
            showReceiving.setForeground(Color.blue);
            showReceived = new TextArea(10, 10);
            Panel north = new Panel();
            north.add(startRece);
            north.add(stopRece);
            add(north, BorderLayout.NORTH);
            Panel center = new Panel();
            center.setLayout(new GridLayout(1, 2));
            center.add(showReceiving);
            center.add(showReceived);
            add(center, BorderLayout.CENTER);
            validate();
            port = 5000;
            try {
                group = InetAddress.getByName("239.255.0.0");
                socket = new MulticastSocket(port);
                socket.joinGroup(group);
            } catch (UnknownHostException ex) {
                Logger.getLogger(Receive.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(Receive.class.getName()).log(Level.SEVERE, null, ex);
            }
            setBounds(100, 50, 360, 380);
            setVisible(true);
            addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
    
            });
        }
    
        public static void main(String[] args) {
            new Receive();
        }
    
        public void run() {
            while (true) {
                byte[] data = new byte[8192];
                DatagramPacket packet = null;
                packet = new DatagramPacket(data, data.length);
                try {
                    socket.receive(packet);
                    String message = new String(packet.getData(), 0, packet.getLength());
                    showReceiving.setText("正在接收的内容\n" + message);
                    showReceived.append(message + "\n");
                } catch (IOException ex) {
                    Logger.getLogger(Receive.class.getName()).log(Level.SEVERE, null, ex);
                }
                if (stoped) {
                    break;
                }
            }
        }
    
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == startRece) {
                startRece.setBackground(Color.blue);
                stopRece.setBackground(Color.gray);
                if (!(thread.isAlive())) {
                    thread = new Thread(this);
                }
                thread.start();
                stoped = false;
            }
            if (e.getSource() == stopRece) {
                startRece.setBackground(Color.gray);
                stopRece.setBackground(Color.blue);
                thread.interrupt();
                stoped = true;
            }
        }
    
    }
    
    

    文中所有源代码链接

    Wu_Being博客声明:本人博客欢迎转载,请标明博客原文和原链接!谢谢!
    《Java组播套接字》:
    http://blog.csdn.net/u014134180/article/details/51675461


    1. 返回到目录 ↩︎

    展开全文
  • 目录 1. udp 1.1 udp通信流程 1.2操作函数 send、sendto recv、recvfrom ...3 组播 ...3.1 组播地址 ...3.2组播通信流程 ...3.3 设置组播属性函数:setsockopt ...3.4 组播代码 ...4. 本地套接字 4.1 结构体soc...

    目录

    1. udp

    1.1 udp通信流程

    1.2 操作函数

    send、sendto

    recv、recvfrom

    2. 广播

    2.1 广播通信流程

    2.2 设置广播属性函数:setsockopt

    2.3 广播代码

    3 组播

    3.1 组播地址

    3.2 组播通信流程

    3.3 设置组播属性函数:setsockopt

    3.4 组播代码

    4. 本地套接字

    4.1 结构体sockaddr_un 

    4.2 本地套接字—进程间通信流程

    4.3 本地套接字—进程间通代码


     

     

    1. udp

     

    1.1 udp通信流程

    • - 服务器端

        - 1.创建通信的套接字
             - int fd = socket( af_inet, SOCK_DGRAM, 0)
        - 2. 绑定 -> 通信的fd 和本地 IP / port 绑定
               - struct sockaddr_in addr;
        - 3.通信
              - 接收数据: recvfrom
              - 发送数据: sendto
        - 4.关闭通信的fd
             - close(fd);

    •   - 客户端

        - 1.创建一个通信的套接字
        - 2.通信
             - 接收数据: recvfrom
             - 发送数据: sendto
        - 3.关闭通信的文件描述符
             - close();

     

    1.2 操作函数

    • send、sendto

    #include <sys/types.h>
    #include <sys/socket.h>
    
    #include <arpa/inet.h>   //也可以只用这一个头文件,包含了上面2个头文件
    
      // tcp 发送数据的函数 write
      ssize_t send(int sockfd, const void *buf, size_t len, int flags);
    
      // udp 发送数据
      ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                            const struct sockaddr *dest_addr, socklen_t addrlen);
      	参数:
      		- sockfd: 通信的fd
    		- buf: 要发送的数据
      		- len: 要发送的数据的长度
      		- flags: 0
              - dest_addr: 通信的另外一端的地址信息
              - addrlen: dest_addr的内存大小

     

    • recv、recvfrom

    #include <sys/types.h>
    #include <sys/socket.h>
    
    #include <arpa/inet.h>   //也可以只用这一个头文件,包含了上面2个头文件
    
      // tcp 接收数据 read
      ssize_t recv(int sockfd, void *buf, size_t len, int flags);
    
      // udp 接收数据函数
      ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                              struct sockaddr *src_addr, socklen_t *addrlen);
      	参数:
      		- sockfd: 通信的fd
      		- buf: 接收数据的一块内存
      		- len: 接收数据的内存(第二个参数)大小
      		- flags: 0
                    - src_addr: 接收谁的数据, 就写入了那个终端的地址信息, 如果不要这部分数据 -> NULL
                    - addrlen: src_addr参数对应内存大小(传入传出参数)
                      
       int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

     

    2. 广播

    向子网中多台计算机发送消息,并且子网中所有的计算机都可以接收到发送方发送的消息。

     

    • 只能在局域网中使用
    • 客户端只要绑定了服务器广播使用的端口, 就可以接收到广播数据

     

    2.1 广播通信流程

    服务器端 -> 广播的一端: 

    • - 创建通信的套接字

                  int fd = socket( af_inet, SOCK_DGRAM, 0);

    • - 设置udp广播属性

                      setsockopt();

    • - 通信 -> 发送广播数据

                    struct sockaddr_in cliaddr;
                    cliaddr.sin_port(8888);    // 广播数据发送到客户端的8888端口, 客户端需要绑定该端口
                    cliaddr.sin_addr.s_addr -> 初始化一个广播地址
                   发送数据: sendto(fd, buf, len, 0, &cliaddr, len);

    • - 关闭通信的fd

                  close(fd);

    客户端

    • - 创建一个通信的套接字

                      int fd = socket( af_inet, SOCK_DGRAM, 0);

    • - 如果想接收广播数据, 需要绑定以固定端口(服务器广播数据使用的端口)

                    struct sockaddr_in cliaddr;
                    cliaddr.sin_port(8888);    
                    bind(fd, cliaddr, len);

    • - 通信

                  接收数据: recvfrom

    • - 关闭通信的文件描述符

                  close();

     

    2.2 设置广播属性函数:setsockopt

    这个函数有许多功能,这里只讨论设置广播属性函数功能

    #include <arpa/inet.h>
    int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
      	参数:
      		- sockfd: 文件描述符
      		- level: SOL_SOCKET
      		- optname: SO_BROADCAST
      		- optval: int数值为1, 允许广播
      		- optlen: optval内存大小

     

    2.3 广播代码

    服务器:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <arpa/inet.h>
    
    int main()
    {
        // 1. 创建通信的套接字
        int fd = socket(AF_INET, SOCK_DGRAM, 0);
        if(fd == -1)
        {
            perror("socket");
            exit(0);
        }
        // 设置广播属性
        int op = 1;
        setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &op, sizeof(op));
        // 将数据发送给客户端, 使用广播地址和固定端口
        // 初始化客户端的地址信息
        struct sockaddr_in cliaddr;
        cliaddr.sin_family = AF_INET;
        cliaddr.sin_port = htons(8989); // 客户端也需要绑定这端口
        inet_pton(AF_INET, "192.168.247.255", &cliaddr.sin_addr.s_addr);
    
        int num = 0;
        // 3. 通信
        while(1)
        {
            // 接收数据
            char buf[128];
            // 发送数据
            sprintf(buf, "hello, client...%d\n ", num++);
            sendto(fd, buf, strlen(buf)+1, 0, (struct sockaddr*)&cliaddr, sizeof(cliaddr));
            printf("广播的数据: %s\n", buf);
            sleep(1);
        }
    
        close(fd);
    
        return 0;
    }
    

    客户端:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <arpa/inet.h>
    
    int main()
    {
        // 1. 创建通信的套接字
        int fd = socket(AF_INET, SOCK_DGRAM, 0);
        if(fd == -1)
        {
            perror("socket");
            exit(0);
        }
    
        // 2. 通信的fd绑定本地的IP和端口
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(8989);
        addr.sin_addr.s_addr = INADDR_ANY;
        int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
        if(ret == -1)
        {
            perror("bind");
            exit(0);
        }
        //inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr.s_addr);
    
        // 3. 通信
        while(1)
        {
            // 接收数据
            char buf[128];
            recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);
            printf("server say: %s\n", buf);
        }
    
        close(fd);
    
        return 0;
    }
    

     

    3 组播

    广播:无论连接到局域网的客户端想不想接收该数据,Server都会给客户端发送该数据。

    进而造成客户端上数据的拥塞,因此引出了组播:Server可以将数据包只发送给指定组内的客户端,而不发送给指定组外的客户端。
     

    特点:

    1. 可以在internet中进行组播
    2. 加入到广播的组织中才可以收到数据

     

    3.1 组播地址

    IP 组播通信必须依赖于 IP 组播地址,在 IPv4 中它的范围从  `224.0.0.0` 到 `239.255.255.255`,并被划分为局部链接多播地址、预留多播地址管理权限多播地址三类:
     

     

     

    3.2 组播通信流程

    服务器端 -> 播的一端: 

    • - 1.创建通信的套接字

                  int fd = socket( af_inet, SOCK_DGRAM, 0);
              - 设置udp组播属性
                      setsockopt();

    • - 2.通信 -> 发送组播数据

                    struct sockaddr_in cliaddr;
                    cliaddr.sin_port(8888);    // 广播数据发送到客户端的8888端口, 客户端需要绑定该端口
                    cliaddr.sin_addr.s_addr -> 初始化一个组播地址
                  发送数据: sendto(fd, buf, len, 0, &cliaddr, len);

    • - 3.关闭通信的fd

                  close(fd);

    客户端

    • - 1.创建一个通信的套接字

                      int fd = socket( af_inet, SOCK_DGRAM, 0);

    • - 2.如果想接收组播数据, 需要绑定以固定端口(服务器组播数据使用的端口)

                      struct sockaddr_in cliaddr;
                    cliaddr.sin_port(8888);    
                      bind(fd, cliaddr, len);

    • - 3.客户端加入到组播网络中

                      setsockopt():

    • - 4.通信

                  接收数据: recvfrom

    • - 5.关闭通信的文件描述符

                  close();

     

    3.3 设置组播属性函数:setsockopt

    这个函数有许多功能,这里只讨论设置组播属性函数功能

      int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
      
      // 服务器端 -> 进程组播
      	参数: 
      		- sockfd: 通信的文件描述符
      		- level: IPPROTO_IP
      		- optname: IP_MULTICAST_IF
      		- optval: struct in_addr
              - optlen: optval 的内存大小
      // 客户端 -> 加入到多播组
      	参数:
      		- sockfd: 通信的文件描述符
      		- level: IPPROTO_IP
      		- optname: IP_ADD_MEMBERSHIP
      		- optval: struct ip_mreqn
             - optlen: optval 的内存大小
              
      struct ip_mreqn
      {
      	// 组播组的IP地址.
      	struct in_addr imr_multiaddr; 
      	// 本地某一网络设备接口的IP地址。
      	struct in_addr imr_address;   
      	int   imr_ifindex;   // 网卡编号
      };

     

    3.4 组播代码

    服务器:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <arpa/inet.h>
    
    int main()
    {
        // 1. 创建通信的套接字
        int fd = socket(AF_INET, SOCK_DGRAM, 0);
        if(fd == -1)
        {
            perror("socket");
            exit(0);
        }
    
        // 设置组播属性
        struct in_addr imr_multiaddr; 
        // 初始化组播地址
        inet_pton(AF_INET, "239.0.0.10", &imr_multiaddr.s_addr);
        setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &imr_multiaddr, sizeof(imr_multiaddr));
    
        // 将数据发送给客户端, 使用广播地址和固定端口
        // 初始化客户端的地址信息
        struct sockaddr_in cliaddr;
        cliaddr.sin_family = AF_INET;
        cliaddr.sin_port = htons(8989); // 客户端也需要绑定这端口
        inet_pton(AF_INET, "239.0.0.10", &cliaddr.sin_addr.s_addr);
    
        int num = 0;
        // 3. 通信
        while(1)
        {
            // 接收数据
            char buf[128];
            // 发送数据
            sprintf(buf, "hello, client...%d\n ", num++);
            sendto(fd, buf, strlen(buf)+1, 0, (struct sockaddr*)&cliaddr, sizeof(cliaddr));
            printf("组播的数据: %s\n", buf);
            sleep(1);
        }
        close(fd);
        return 0;
    }

    客户端:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <arpa/inet.h>
    #include <net/if.h>
    
    int main()
    {
        // 1. 创建通信的套接字
        int fd = socket(AF_INET, SOCK_DGRAM, 0);
        if(fd == -1)
        {
            perror("socket");
            exit(0);
        }
    
        // 2. 通信的fd绑定本地的IP和端口
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(8989);
        addr.sin_addr.s_addr = INADDR_ANY;
        int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
        if(ret == -1)
        {
            perror("bind");
            exit(0);
        }
        //inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr.s_addr);
        // 加入到组播
        struct ip_mreqn op;
        op.imr_address.s_addr = INADDR_ANY; // 本地地址
        inet_pton(AF_INET, "239.0.0.10", &op.imr_multiaddr.s_addr);
        op.imr_ifindex = if_nametoindex("ens33");
    
        setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &op, sizeof(op));
        // 3. 通信
        while(1)
        {
            // 接收数据
            char buf[128];
            recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);
            printf("server say: %s\n", buf);
        }
        close(fd);
        return 0;
    }
    

     

    4. 本地套接字

    本地套接字用于进程间通信,有没有血缘关系都可以。通信流程 -> 一般按照tcp流程处理

     

    4.1 结构体sockaddr_un 

    结构体 sockaddr、sockaddr_in用于网络通信

    结构体 sockaddr_un用于进程间通信

    结构体 sockaddr_in用于ipv6通信

    由于结构体sockaddr需要用指针偏移添加IP地址,这样很麻烦,在网络通信中我们使用sockaddr_in来添加端口号、IP地址。再强转成sockaddr类型,因为这2个结构体大小一样,后面的服务器—客户端程序会有具体体现。

    在进程间通信中,使用sockaddr_un

    #include <sys/un.h>
    
    #define UNIX_PATH_MAX 108
    
    struct sockaddr_un 
    {
      	sa_family_t sun_family; // 地址族协议 af_local
      	char sun_path[UNIX_PATH_MAX];	// 套接字文件的路径, 这是一个伪文件, 大小永远=0
    };

     

    4.2 本地套接字—进程间通信流程

    进程1:服务器端

    • 1. 创建监听的套接字

          int lfd = socket(af_local, sock_stream, 0);
              第一个参数: AF_UNIX, AF_LOCAL

    • 2. 监听的套接字绑定本地的 套接字文件-> server端

          struct sockaddr_un addr;
          // 绑定成功之后, 指定的sun_path中的套接字文件会自动生成
          bind(lfd, addr, len);

    • 3. 监听

          listen(lfd, 100);

    • 4. 等待并接受连接请求

          struct sockaddr_un cliaddr;
          int connfd  = accept(lfd, cliaddr, len);

    • 5. 通信

          接收数据: read/recv
          发送数据: write/send

    • 6. 关闭连接

          close();

    进程2:客户端

    •   1. 创建通信的套接字

          int fd = socket(af_local, sock_stream, 0);

    •   2. 监听的套接字绑定本地的IP 端口

          struct sockaddr_un addr;
          // 绑定成功之后, 指定的sun_path中的套接字文件会自动生成
          bind(fd, addr, len);

    •   3. 连接服务器

          struct sockaddr_un serveraddr;
          connect(fd, serveraddr, sizeof(serveraddr));

    •   4. 通信

          接收数据: read/recv
          发送数据: write/send

    •   5. 关闭连接

          close();

     

    4.3 本地套接字—进程间通代码

    进程1:服务器

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <arpa/inet.h>
    #include <sys/un.h>
    
    int main()
    {
        unlink("server.sock");
        // 1. 创建监听的套接字
        int lfd = socket(AF_LOCAL, SOCK_STREAM, 0);
        if(lfd == -1)
        {
            perror("socket");
            exit(0);
        }
    
        // 2. 绑定本地套接字文件
        struct sockaddr_un addr;
        addr.sun_family = AF_LOCAL;
        strcpy(addr.sun_path, "server.sock");       //套接字文件是伪文件,会自动生成,名字后缀随便取
        int ret = bind(lfd, (struct sockaddr*)&addr, sizeof(addr));
        if(ret == -1)
        {
            perror("bind");
            exit(0);
        }
    
        // 3. 监听
        ret = listen(lfd, 100);
        if(ret == -1)
        {
            perror("listen");
            exit(0);
        }
    
        // 4. 等待并接受连接请求
        struct sockaddr_un cliaddr;
        int len = sizeof(cliaddr);
        int connfd = accept(lfd, (struct sockaddr*)&cliaddr, &len);
        if(connfd == -1)
        {
            perror("accept");
            exit(0);
        }
        printf("client socket fileName: %s\n", cliaddr.sun_path);
    
        // 5. 通信
        while(1)
        {
            // 接收数据
            char buf[128];
            int nums = recv(connfd, buf, sizeof(buf), 0);
            if(nums == -1)
            {
                perror("recv");
                exit(0);
            }
            else if(nums == 0)
            {
                printf("client disconnect...\n");
                break;
            }
            else
            {
                printf("client say: %s\n", buf);
                send(connfd, buf, nums, 0);
            }
        }
        close(connfd);
        close(lfd);
        return 0;
    }
    

    进程2:客户端

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <arpa/inet.h>
    #include <sys/un.h>
    
    int main()
    {
        unlink("client.sock");
        // 1. 创建通信的套接字
        int cfd = socket(AF_LOCAL, SOCK_STREAM, 0);
        if(cfd == -1)
        {
            perror("socket");
            exit(0);
        }
    
        // 2. 绑定本地套接字文件
        struct sockaddr_un addr;
        addr.sun_family = AF_LOCAL;
        strcpy(addr.sun_path, "client.sock");
        // 绑定成功, client.sock会自动生成
        int ret = bind(cfd, (struct sockaddr*)&addr, sizeof(addr));
        if(ret == -1)
        {
            perror("bind");
            exit(0);
        }
    
    
        // 3. 连接服务器
        struct sockaddr_un seraddr;
        seraddr.sun_family = AF_LOCAL;
        strcpy(seraddr.sun_path, "server.sock");
        ret = connect(cfd, (struct sockaddr*)&seraddr, sizeof(seraddr));
        if(ret == -1)
        {
            perror("connect");
            exit(0);
        }
    
        int num = 0;
        // 5. 通信
        while(1)
        {
            // 发送数据 
            char buf[128];
            sprintf(buf, "hello, everyone... %d\n", num++);
            send(cfd, buf, strlen(buf)+1, 0);
            printf("client say: %s\n", buf);
    
            // 接收数据
            int nums = recv(cfd, buf, sizeof(buf), 0);
            if(nums == -1)
            {
                perror("recv");
                exit(0);
            }
            else if(nums == 0)
            {
                printf("server disconnect...\n");
                break;
            }
            sleep(1);
        }
        close(cfd);
        return 0;
    }
    

     

     

     

     

     

     

     

     

    展开全文
  • 关于QT中UDP套接字组播简单说明 关于linux的UDP传输: 关于QT的UDP传输: 与TCP不同的是, TCP的服务端套接字需要通信套接字和监听套接字, 客户端需要通信套接字, 而在UDP中, 双方只需要UDP套接字, 也就是一个通信...

    关于QT中UDP套接字和组播简单说明

    关于linux的UDP传输:

    在这里插入图片描述

    关于QT的UDP传输:

    在这里插入图片描述

    与TCP不同的是, TCP的服务端套接字需要通信套接字和监听套接字, 客户端需要通信套接字, 而在UDP中, 双方只需要UDP套接字, 也就是一个通信套接字即可.
    UDP服务端的QUdpSocket对象只需用**.bind()绑定端口, 然后客户端就可以用writeDatagram(str, ip, port)就可以进行数据传输.
    服务端接收数据时会触发
    readyRead信号**, 便可以使用**readDatagram(str, strMax, ip, port)**来存放接收的数据.
    对于数据传输不太理解的可以参考这个: https://blog.csdn.net/qq_36394394/article/details/105910504

    关于组播的简单介绍:

    使用组播需要的地址是D类地址.

    那么他的作用是什么呢?

    一般来说, 我们使用例如255.255.255.255(本地局域网)发送数据包(广播) , 位于这个局域网的的所有用户是都能接收到这个数据, 但是你接收了 数据, 数据包是否能呈现出来取决于你的端口是否接收.
    可是广播有个缺点, 就是我们有时总是广播的时候, 这个网络很容易出现阻塞, 这时候我们就需要组播了.

    QT中组播怎么实现呢?

    前提: 使用组播需要的地址是D类地址.
    我们连接某段地址, 在这个地址段中, 数据包广播, 需要数据的就加入, 这样就不容易导致网络阻塞

    1. 绑定端口需要绑到 ipv4
      QUdpSocket对象使用 .bind(QHostAddress::AnyIPv4, port);
    2. 加入某个组播
      QUdpSocket对象使用 .joinMulticastGroup( QHostAddress(“ip”) );

    关于组播组的介绍

    组播组可以是永久的也可以是临时的。组播组地址中,有一部分由官方分配的,称为永久组播组。永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化。永久组播组中成员的数量都可以是任意的,甚至可以为零。那些没有保留下来供永久组播组使用的ip组播地址,可以被临时组播组利用。

    1. 224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;

    2. 224.0.1.0~224.0.1.255是公用组播地址,可以用于Internet;

    3. 224.0.2.0~238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;

    .2.0~238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;

    1. 239.0.0.0~239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。
    展开全文
  • Java 多播套接字

    千次阅读 2012-03-29 11:22:37
    数据报套接字类用于发送和接收 IP 多包。MulticastSocket 是一种 (UDP) DatagramSocket,它具有加入 Internet 上其他多主机的“”的附加功能。  1、IP多地址和多播组  IP多通信必须依赖于IP多...
    多播数据报套接字类用于发送和接收 IP 多播包。MulticastSocket 是一种 (UDP) DatagramSocket,它具有加入 Internet 上其他多播主机的“组”的附加功能。
    

          1、IP多播地址和多播组

               IP多播通信必须依赖于IP多播地址。在IPv4中它是一个D类IP地址,范围从224.0.0.0到239.255.255.255,地址 224.0.0.0 被保留,不应使用。 并被划分为局部链接多播地址、预留多播地址和管理权限多播地址三类。其中,局部链接多播地址范围在224.0.0.0~224.0.0.255,这是为路由协议和其它用途保留的地址,路由器并不转发属于此范围的IP包;预留多播地址为224.0.1.0~238.255.255.255,可用于全球范围(如 Internet)或网络协议;管理权限多播地址为239.0.0.0~239.255.255.255,可供组织内部使用,类似于私有IP地址,不能用于Internet,可限制多播范围。

     

          使用同一个IP多播地址接收多播数据包的所有主机构成了一个主机组,也称为多播组。一个多播组的成员是随时变动的,一台主机可以随时加入或离开多播组,多播组成员的数目和所在的地理位置也不受限制,一台主机也可以属于几个多播组。此外,不属于某一个多播组的主机也可以向该多播组发送数据包。


          2、加入或退出多播组

               可以通过使用所需端口创建 MulticastSocket,然后调用 joinGroup(InetAddress groupAddr) 方法来加入多播组。

          套接字通过 leaveGroup(InetAddress addr) 方法放弃组中的成员资格。

     

          3、发送或接收数据包

               当套接字预定多播组/端口时,像所有其他成员一样(组和端口相同),它将接收其他成员发送的数据报。
               将消息发送到多播组时,该主机和端口的所有预定接收者都将接收到消息(在数据包的生存范围内)。套接字不必成为多播组的成员即可向其发送消息。


          4、多个 MulticastSocket 可以同时预定多播组和端口,并且都会接收到组数据包。

     

          5、不允许 applet 使用多播套接字。

    // join a Multicast group and send the group salutations
    String msg = "Hello";
    InetAddress group = InetAddress.getByName("228.5.6.7");
    MulticastSocket s = new MulticastSocket(6789);
    s.joinGroup(group);
    DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(), group, 6789);
    s.send(hi);
    // get their responses!
    byte[] buf = new byte[1000];
    DatagramPacket recv = new DatagramPacket(buf, buf.length);
    s.receive(recv);
    ...
    // OK, I'm done talking - leave the group...
    s.leaveGroup(group);


    参考文章:

    http://blog.csdn.net/daviyang35/archive/2007/05/14/1608013.aspx


    展开全文
  • W5500双套接字通信

    2018-10-18 10:28:09
    W5500可以开两个套接字,并运行于不同模式下吗?答案是肯定的!亲测可用的配置,S0运行于UDP,S1运行于TCP_CLIENT,拿走不谢
  • 播套接字选项分析

    千次阅读 2017-07-31 11:21:57
    3)、单个主机上多个套接字加入相同的特定于源的多播组,这样,单个套接字的抹除并影响其他套接字的关系。 七、IP_MULTICAST_IF和IPV6_MULTICAST_IF 指定通过本套接字发的多数据报的外出接口。 1)...
  • 原始套接字学习总结

    千次阅读 2016-05-06 11:24:17
    raw socket(原始套接字)工作原理与规则 原始套接字是一个特殊的套接字类型,它的创建方式跟TCP/UDP创建方法几乎是 一摸一样,例如,通过  int sockfd;  sockfd = socktet(AF_INET, SOCK_RAW, IPPROTO_ICMP); ...
  • Python黑帽第二篇文章将分享Python网络攻防基础知识,看看Python能做什么,以及正则表达式、网络爬虫和套接字通信入门基础。本文参考了i春秋ADO老师的课程内容,这里真心推荐大家去学习ichunqiu的课程,同时也结合...
  • SOCKET套接字选项

    千次阅读 2015-07-14 12:43:46
     在Linux网络编程中,有时需要设置地址复用,允许发送广播包,将主机加入某个多播组,设置发送与接收缓冲区的大小,设置发送与接收的超时时间,将套接字绑定到某个接口上,发送TCP探测包查看客户端是否保持连接等,...
  • 套接字选项

    千次阅读 2013-10-30 13:56:41
    获得与给定套接字相关的相关信息。其定义如下: int getsocketopt( SOCKET s, int level, int optname, char FAR* optval, int FAR* optlen ); s:其为一个给定的套接字,这个套接字必须有效 level:为一个选项
  • 使用套接字实现多通信

    千次阅读 2011-10-26 14:53:17
    通信需要如下三个条件: (1)使用UDP传输协议 (2)使用多地址(224.0.0.1-239.255.255.255) (3)另外需要中间的所有路由器都需要支持多协议才可以。 需要注意的一点: 在MSDN中关于setsockopt()函数有一...
  • Linux原始套接字学习总结

    千次阅读 2016-05-06 12:00:20
    Linux网络编程:原始套接字的魔力【上】 http://blog.chinaunix.net/uid-23069658-id-3280895.html 基于原始套接字编程  在开发面向连接的TCP和面向无连接的UDP程序时,我们所关心的核心问题在于数据收发...
  • 链路层套接字

    千次阅读 2016-08-14 13:57:29
    最近看了下udhcp的源代码,其中会根据LISTEN_MODE建立不同的socket进行通信,一个是普通的传输层UDP套接字,另外一个是链路层的套接字,由于本人才疏学浅,所以在网上搜罗了一下有关链路层套接字的东东,在此记录...
  • 一、设置套接字选项(zmq_setsockopt) 二、获取套接字选项(zmq_getsockopt)
  • linux下原始套接字编程

    千次阅读 2017-03-13 19:35:51
    1. 面向IP层的原始套接字编程 -----------------------------------------------------------------------------------------------------------------------------  socket(AF_INET,SOCK_RAW,protocol)  [1]. ...
  • AF_INET套接字支持,但是packet 套接字不支持(不过,可以使用bind函数绑定地址) 如果有多个接口,例如eth0, eth1, ethx......,就可以在创建套接字的时候绑定相应的接口发送数据,例如我的电脑里有两个接口 : ...
  • Qt套接字编程

    千次阅读 2011-08-04 14:29:59
    网络编程,OSI(开放式系统互联参考模型)七层参考模型:应用层、表示层、会话层、传输层、... 套接字(Socket)是网络通信的基本构建模块,又分为流式套接字(Stream Socket)和数据报套接字(Datagram Socket)两种类型的
  • Unix 通用套接字选项

    千次阅读 2013-07-13 10:30:23
    当一个TCP 套接字开启本选项时,内核将为TCP在该套接字发送和接收的所有分组保留详细跟踪信息。 SO_ERROR: 套接字发生错误时,待处理错误。 SO_KEEPALIVE :给一个TCP 套接字设置保持存活选项后,如果2小时内在该套接...
  • socket套接字及缓冲区详解

    千次阅读 多人点赞 2018-10-15 17:16:34
    我们可以用套接字中的相关函数来完成通信过程。   套接字的特性有三个属性确定,它们是:域(domain),类型(type),和协议(protocol)。 #include&amp;amp;lt;sys/types.h&amp;amp;gt; #include&...
  • // 多播套接字 private static InetAddress group; private static boolean isFirst; // 是否信息记录里的第一条信息 public Multicast() { setTitle("多播群聊室"); setSize(450, 400); int width = ...
  • 这里是在 ubuntu 下通过原始套接字组一个 udp 数据包,给 PC 机的网络调试助手发送信息: #include #include #include #include <net/if.h> //struct ifreq #include <sys/ioctl.h> //ioctl、SIOCGIFADDR #...
  • 原始套接字发送IP数据报

    千次阅读 2019-04-16 10:24:30
    一样:构造套接字,填写地址数据结构,填充构造发送报文,调用sendto发送。  通过以下构造套接字: int sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP) );  由于我们想自己构造IP头,自己计算校验...
  • UDP套接字

    千次阅读 2011-01-04 15:56:00
    <br /> 1 UDP套接字 <br /> 数据报(Datagram)是网络层数据单元在介质上传输信息的一种逻辑分组格式,它是一种在网络中传播的、独立的、自身包含地址信息的消息,它能否到达目的地、到达的时间、到达...
  • 建立高度分布式、网络化的应用程序和服务,就需要对套接字和其他关键的网络API有深入的理解。本书为在各种环境下建立健壮的、高性能的网络系统提供了全面的指导。 这个版本建立在W.Richard Stevens的传奇性工作的...
  • 建立高度分布式、网络化的应用程序和服务,就需要对套接字和其他关键的网络API有深入的理解。本书为在各种环境下建立健壮的、高性能的网络系统提供了全面的指导。 这个版本建立在W.Richard Stevens的传奇性工作的...
  • 前文分享了Wireshark抓包原理知识,并结合NetworkMiner工具抓取了图像资源和用户名密码,本文将讲解Python网络攻防相关基础知识,包括正则表达式、Web编程和套接字通信。本文参考了爱春秋ADO老师的课程内容,这里也...
  • UDP组播的发送与接收代码示例

    千次阅读 2019-06-28 20:34:56
    组播包的发送和接收依然是通过UDP套接字来实现。组播包发送的流程如下所示。 (1)创建UDP套接字。 (2)指定目标地址和端口。 (3)发送数据包。 1 #include <stdio.h> 2 #include <arpa/inet.h> 3 ...
  • 原始套接字SOCK_RAW发送UDP数据包

    千次阅读 2016-02-24 20:22:21
    使用原始套接字发送udp数据包,从传输层封包到链路层(mac头+ip头+udp头)。udp数据包,从传输层封包到链路层(mac头+ip头+udp头)。     head.h文件如下:   #ifndef _HEAD_H #define _HEAD_H #...
  • 在看一本安全编程书的时候读到原始套接字地方,自己也尝试写了下来,将遇到的一个问题发出来。 // 原始套接字数据的接收.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "stdio.h" #...
  • 6.套接字与接口(套接字变量 = 套接字描述符 = 套接字标识符) 我们惊奇地注意到,套接字描述符符与端口号有着一些令人惊奇地相似之处:它们都是整形数据,都是对通信的标识。 可是,它们的不同之处在哪里呢? ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 37,080
精华内容 14,832
关键字:

组播要用什么套接字