zoukankan      html  css  js  c++  java
  • socket通信

    1. 概念

    1.1 C/C++中socket

    #include <sys/socket.h> 
    int socket(int family, int type, int protocol);   //指定期望的通信协议类型,返回的文件描述符和套接字描述符类似,我们称为套接字描述符,简称sockfd  

    family:协议族

    family 说明
    AF_INET IPv4协议 
    AF_INET6 IPv6
    AF_LOCAL Unix域协议
    AF_ROUTE  路由套接字
    AF_KEY 密钥套接字
    AF_UNIX 本地通信

    type:套接字的类型

    type 说明
    SOCK_STREAM 字节流套接字
    SOCK_DGRAM 数据报套接字
    SOCK_SEQPACKET  有序分组套接字
    SOCK_RAW 原始套接字

    protocol:协议类型的常量或设置为0,以选择给定的family和type组合的系统默认值

    protocol 说明
    IPPROTO_TCP TCP传输协议
    IPPROTO_UDP UDP传输协议
    IPPROTO_SCTP SCTP传输协议

    1.2 Android应用层socket

    2. 本地通信代码(android和Linux的区别)

    2.1 android和Linux下socket本地通信的区别

    在Linux中的本地通信有两种方式:1.创建socket文件,通过文件与客户端socket通信;2.不创建socket文件

    在android中无法创建socket文件(应该可以创建,只是我不知道怎么去创建而已)所以只能使用第二种不创建的方式

    服务端示例代码:

    #include <sys/types.h>  
    #include <sys/socket.h>  
    #include <stdio.h>  
    #include <sys/un.h>  
    #include <unistd.h>  
    #include <stdlib.h> 
    #include <stddef.h>
    
    
    int main(){
        
        int fd;
        int client_fd;
        struct sockaddr_un server_address;// 套接字
        char ch_send, ch_recv;
        int server_len, client_len;
        int i;
        
        memset(&server_address, 0, sizeof(server_address));
        
        //必须删除,如果之前有这个文件,则会报错!
        unlink("server_socket");
        //1. 创建一个socket:本地通信协议;字节流方式;
        fd = socket(AF_UNIX, SOCK_STREAM, 0);
        printf("1
    ");
        //填充套接字
        server_address.sun_family = AF_UNIX;
        //这里是socket文件名,client就是用这个文件来通信
        //strcpy (server_address.sun_path, "server_socket");
        server_address.sun_path[0]='';
        strcpy (server_address.sun_path+1, "server_socket");
        //server_len = strlen(SERVER_NAME)  + offsetof(sockaddr_un, sun_path);  
        //printf("offsetof(struct sockaddr_un, sun_path)=%d
    ", offsetof(struct sockaddr_un, sun_path));
        server_len = offsetof(struct sockaddr_un, sun_path) + strlen(server_address.sun_path+1)+1;
        printf("server_len=%d
    ", server_len);
        printf("2
    ");
        //2. 绑定
        bind(fd, (struct sockaddr *)&server_address, server_len);
        printf("3
    ");
        //3. 被动接收listen
        listen (fd, 5);
        printf("4
    ");
        //4. 监听accept
        client_fd = accept(fd, (struct sockaddr *)&server_address, (socklen_t *)&client_len);
        printf("5
    ");
        //测试发送接收
        for (i = 0, ch_send = '1'; i < 5; i++, ch_send++) { 
            //没数据则会阻塞在这里
            printf("阻塞
    ");
            if (read (client_fd, &ch_recv, 1) == -1) {  
                perror ("read1");  
                exit (EXIT_FAILURE);  
            }
            printf ("服务端接收到的数据为: %c
    ", ch_recv);  
            
            sleep (1);  
            
            //发送数据
            if (write (client_fd, &ch_send, 1) == -1) {  
                perror ("read2");  
                exit (EXIT_FAILURE);  
            }  
        }  
        //关闭客户端socket连接
        close (client_fd);  
        unlink("server_socket");
    }

    客户端示例代码:

    #include <sys/types.h>  
    #include <sys/socket.h>  
    #include <stdio.h>  
    #include <sys/un.h>  
    #include <unistd.h>  
    #include <stdlib.h>  
    #include <stddef.h>
    
    int main (int argc, char *argv[])  
    {  
        struct sockaddr_un address;  
        int sockfd;  
        int len;  
        int i, bytes;  
        int result;  
        char ch_recv, ch_send;  
          
        /*创建socket,AF_UNIX通信协议,SOCK_STREAM数据方式*/  
        if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {  
            perror ("socket");  
            exit (EXIT_FAILURE);  
        }  
          
        address.sun_family = AF_UNIX;  
        //strcpy (address.sun_path, "server_socket");  
        address.sun_path[0]='';
        strcpy (address.sun_path+1, "server_socket"); 
     
        //len = sizeof (address);  
        len = offsetof(struct sockaddr_un, sun_path) + strlen(address.sun_path+1)+1;
        /*向服务器发送连接请求*/  
        result = connect (sockfd, (struct sockaddr *)&address, len);  
            if (result == -1) {  
                printf ("ensure the server is up
    ");  
                perror ("connect");  
                exit (EXIT_FAILURE);  
        }  
          
        for (i = 0, ch_send = 'A'; i < 5; i++, ch_send++) {  
            if ((bytes = write(sockfd, &ch_send, 1)) == -1) { /*发消息给服务器*/  
                perror ("write");  
                exit (EXIT_FAILURE);  
            }  
              
            sleep (2); /*休息二秒钟再发一次*/  
              
            if ((bytes = read (sockfd, &ch_recv, 1)) == -1) { /*接收消息*/  
                perror ("read");  
                exit (EXIT_FAILURE);  
            }  
              
            printf ("客户端接收到的数据为: %c
    ", ch_recv);  
        }  
        close (sockfd);  
          
        return (0);  
    }  

     

    参考资料:

    http://docs.huihoo.com/c/linux-c-programming/ch37s04.html

    http://blog.csdn.net/ccwwff/article/details/45693469

    http://www.xuebuyuan.com/726129.html

  • 相关阅读:
    关于JAVA的线程问题
    Java 对JTextField添加回车响应
    Failed to install *.apk on device 'emulator-5554': timeout .
    静态属性
    类与对象的实例属性

    面向对象2
    面向对象设计
    re模块,主要用来查询
    xml对标签操作,
  • 原文地址:https://www.cnblogs.com/maogefff/p/7955306.html
Copyright © 2011-2022 走看看