网络编程7:本地套接字

2023-05-16

1. 基于UDP的网络编程

1.1 TCP通信和UDP通信各自的优缺点

    TCP:    面向连接的,可靠数据包传输。对于不稳定的网络层,采取完全弥补的通信方式。 丢包重传。

        优点:
            稳定。        
                数据流量稳定、速度稳定、顺序
        缺点:
            传输速度慢。相率低。开销大。

        使用场景:数据的完整型要求较高,不追求效率。

              大数据传输、文件传输。


    UDP:    无连接的,不可靠的数据报传递。对于不稳定的网络层,采取完全不弥补的通信方式。 默认还原网络状况

        优点:

            传输速度块。相率高。开销小。

        缺点:
            不稳定。
                数据流量。速度。顺序。


        使用场景:对时效性要求较高场合。稳定性其次。

              游戏、视频会议、视频电话。        腾讯、华为、阿里  ---  应用层数据校验协议,弥补udp的不足。

1.2 UDP实现的 C/S 模型

(1)实现的具体思路:

    recv()/send() 只能用于 TCP 通信。 替代 read、write
    accpet(); ---- Connect(); ---被舍弃
    server:
        lfd = socket(AF_INET, STREAM, 0);    SOCK_DGRAM --- 报式协议。
        bind();
        listen();  --- 可有可无
        while(1){
            read(cfd, buf, sizeof) --- 被替换 --- recvfrom() --- 涵盖accept传出地址结构。
                ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
                    sockfd: 套接字
                    buf:缓冲区地址
                    len:缓冲区大小
                    flags: 0
                    src_addr:(struct sockaddr *)&addr 传出。 对端地址结构
                    addrlen:传入传出。
                返回值: 成功接收数据字节数。 失败:-1 errn。 0: 对端关闭。
            小-- 大                
            write();--- 被替换 --- sendto()---- connect
                 ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
                    sockfd: 套接字
                    buf:存储数据的缓冲区
                    len:数据长度
                    flags: 0
                    src_addr:(struct sockaddr *)&addr 传入。 目标地址结构
                    addrlen:地址结构长度。
                返回值:成功写出数据字节数。 失败 -1, errno        
        }

        close();
    client:
        connfd = socket(AF_INET, SOCK_DGRAM, 0);
        sendto(‘服务器的地址结构’, 地址结构大小)
        recvfrom()
        写到屏幕
        close();

(2)代码如下:

服务器端,server.c

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <ctype.h>

#define SERV_PORT 8000

int main(void)
{
    struct sockaddr_in serv_addr, clie_addr;
    socklen_t clie_addr_len;
    int sockfd;
    char buf[BUFSIZ];
    char str[INET_ADDRSTRLEN];
    int i, n;

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(SERV_PORT);

    bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));

    printf("Accepting connections ...\n");
    while (1) {
        clie_addr_len = sizeof(clie_addr);
        n = recvfrom(sockfd, buf, BUFSIZ,0, (struct sockaddr *)&clie_addr, &clie_addr_len);
        if (n == -1)
            perror("recvfrom error");

        printf("received from %s at PORT %d\n",
                inet_ntop(AF_INET, &clie_addr.sin_addr, str, sizeof(str)),
                ntohs(clie_addr.sin_port));

        for (i = 0; i < n; i++)
            buf[i] = toupper(buf[i]);

        n = sendto(sockfd, buf, n, 0, (struct sockaddr *)&clie_addr, sizeof(clie_addr));
        if (n == -1)
            perror("sendto error");
    }

    close(sockfd);

    return 0;
}

客户端,clent.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <ctype.h>

#define SERV_PORT 8000

int main(int argc, char *argv[])
{
    struct sockaddr_in servaddr;
    int sockfd, n;
    char buf[BUFSIZ];

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
    servaddr.sin_port = htons(SERV_PORT);

    bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

    while (fgets(buf, BUFSIZ, stdin) != NULL) {
        n = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
        if (n == -1)
            perror("sendto error");

        n = recvfrom(sockfd, buf, BUFSIZ, 0, NULL, 0);         //NULL:不关心对端信息
        if (n == -1)
            perror("recvfrom error");

        write(STDOUT_FILENO, buf, n);
    }

    close(sockfd);

    return 0;
}

2. IP地址转换函数

2.1 点分文本的IP地址与二进制网络字节序的转换

早期:inet_aton、inet_ntoa

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp);
in_addr_t inet_addr(const char *cp);
char *inet_ntoa(struct in_addr in);

只能处理IPv4的ip地址,不可重入函数,注意参数是struct in_addr

现在:inet_pton、inet_ntop

inet_pton:将“点分十进制” -> “二进制整数”

#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

支持IPv4和IPv6,可重入函数,其中inet_pton和inet_ntop不仅可以转换IPv4的in_addr,还可以转换IPv6的in6_addr。因此函数接口是void *addrptr。

2.2 sockaddr数据结构

        strcut sockaddr 很多网络编程函数诞生早于IPv4协议,那时候都使用的是sockaddr结构体,为了向前兼容,现在sockaddr退化成了(void *)的作用,传递一个地址给函数,至于这个函数是sockaddr_in还是sockaddr_in6,由地址族确定,然后函数内部再强制类型转化为所需的地址类型。

sockaddr数据结构

struct sockaddr {
	sa_family_t sa_family; 		/* address family, AF_xxx */
	char sa_data[14];			/* 14 bytes of protocol address */
};

使用 sudo grep -r "struct sockaddr_in {"  /usr 命令可查看到struct sockaddr_in结构体的定义。一般其默认的存储位置:/usr/include/linux/in.h 文件中。

/* ipv4地址结构体 */
struct sockaddr_in {
	__kernel_sa_family_t sin_family; 			/* Address family */  	地址结构类型
	__be16 sin_port;					 		/* Port number */		端口号
	struct in_addr sin_addr;					/* Internet address */	IP地址
	/* Pad to size of `struct sockaddr'. */
	unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
	sizeof(unsigned short int) - sizeof(struct in_addr)];
};

struct in_addr {						/* Internet address. */
	__be32 s_addr;
};

/* 本地套接字对应的地址结构体 */
#define UNIX_PATH_MAX 108
	struct sockaddr_un {
	__kernel_sa_family_t sun_family; 	/* AF_UNIX */
	char sun_path[UNIX_PATH_MAX]; 	/* pathname */
};

/* ipv6地址结构体 */
struct sockaddr_in6 {
	unsigned short int sin6_family; 		/* AF_INET6 */
	__be16 sin6_port; 					/* Transport layer port # */
	__be32 sin6_flowinfo; 				/* IPv6 flow information */
	struct in6_addr sin6_addr;			/* IPv6 address */
	__u32 sin6_scope_id; 				/* scope id (new in RFC2553) */
};

struct in6_addr {
	union {
		__u8 u6_addr8[16];
		__be16 u6_addr16[8];
		__be32 u6_addr32[4];
	} in6_u;
	#define s6_addr 		in6_u.u6_addr8
	#define s6_addr16 	in6_u.u6_addr16
	#define s6_addr32	 	in6_u.u6_addr32
};

        Pv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位端口号和32位IP地址,IPv6地址用sockaddr_in6结构体表示,包括16位端口号、128位IP地址和一些控制字段。UNIX Domain Socket的地址格式定义在sys/un.h中,用sock-addr_un结构体表示。各种socket地址结构体的开头都是相同的,前16位表示整个结构体的长度(并不是所有UNIX的实现都有长度字段,如Linux就没有),后16位表示地址类型。IPv4、IPv6和Unix Domain Socket的地址类型分别定义为常数AF_INET、AF_INET6、AF_UNIX。这样,只要取得某种sockaddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容。因此,socket API可以接受各种类型的sockaddr结构体指针做参数,例如bind、accept、connect等函数,这些函数的参数应该设计成void *类型以便接受各种类型的指针,但是sock API的实现早于ANSI C标准化,那时还没有void *类型,因此这些函数的参数都用struct sockaddr *类型表示,在传递参数之前要强制类型转换一下,例如:

struct sockaddr_in servaddr;
bind(listen_fd, (struct sockaddr *)&servaddr, sizeof(servaddr));		/* initialize servaddr */

3. 本地套接字

进程间通信常用的方法如下,今天重点讲本地套(domain)--- CS模型。

IPC: pipe、fifo、mmap、信号、本地套(domain)--- CS模型

3.1 本地套接字的使用区别

(1)int socket(int domain, int type, int protocol);

参数 domain:网络编程选择AF_INET ,本地套接字选择AF_UNIX或AF_LOCAL;

参数type:TCP对应SOCK_STREAM,UDP对应SOCK_DGRAM,本地套接字SOCK_STREAM/SOCK_DGRAM都可以;

(2)地址结构sockaddr

TCP本地套接字
struct sockaddr_in srv_addr; struct sockaddr_un srv_adrr;

srv_addr.sin_family = AF_INET;

srv_addr.sin_port = htons(8888); 

srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

srv_addr.sun_family = AF_UNIX;

strcpy(srv_addr.sun_path, "srv.socket")

len = offsetof(struct sockaddr_un, sun_path) + strlen("srv.socket");

bind(fd, (struct sockaddr *)&srv_addr, sizeof(srv_addr));bind(fd, (struct sockaddr *)&srv_addr, len); 

(3)使用unlink保证bind成功

bind()函数调用成功,会创建一个 socket。因此为保证bind成功,通常我们在 bind之前, 可以使用 unlink("srv.socket");

(4)客户端不能依赖 “隐式绑定”。并且应该在通信建立过程中,创建且初始化2个地址结构:
        1) client_addr --> bind()
        2)  server_addr --> connect();

3.2 对比网络套接字与本地套接字的编程思想

server端:

TCP本地套接字
lfd = socket(AF_INET, SOCK_STREAM, 0);lfd = socket(AF_UNIX, SOCK_STREAM, 0);
bzero() ---- struct sockaddr_in serv_addr;bzero() ---- struct sockaddr_un serv_addr, clie_addr;

serv_addr.sin_family = AF_INET;

serv_addr.sin_port = htons(8888);

serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

serv_addr.sun_family = AF_UNIX;    

strcpy(serv_addr.sun_path, "套接字文件名")

len = offsetof(sockaddr_un, sun_path) + strlen();

bind(lfd, (struct sockaddr *)&serv_addr, sizeof());

unlink("套接字文件名");

bind(lfd, (struct sockaddr *)&serv_addr, len);  创建新文件

cfd = Accept(lfd, ()&clie_addr, &len);cfd = Accept(lfd, ()&clie_addr, &len);

client端:

TCP本地套接字
lfd = socket(AF_INET, SOCK_STREAM, 0);lfd = socket(AF_UNIX, SOCK_STREAM, 0);
" 隐式绑定 IP+port"

bzero() ---- struct sockaddr_un clie_addr;

clie_addr.sun_family = AF_UNIX;

strcpy(clie_addr.sun_path, "client套接字文件名")

len = offsetof(sockaddr_un, sun_path) + strlen();

unlink( "client套接字文件名");

bind(lfd, (struct sockaddr *)&clie_addr, len);

bzero() ---- struct sockaddr_in serv_addr;

serv_addr.sin_family = AF_INET;    

inet_pton(AF_INT, "服务器IP", &sin_addr.s_addr);

serv_addr.sin_port = htons("服务器端口");    

bzero() ---- struct sockaddr_un serv_addr;

serv_addr.sun_family = AF_UNIX;

strcpy(serv_addr.sun_path, "server套接字文件名")

len = offsetof(sockaddr_un, sun_path) + strlen();

connect(lfd, &serv_addr, sizeof());connect(lfd, &serv_addr, len);

3.3 本地套接编程domain_socket

server.c

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <strings.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <stddef.h>

#include "wrap.h"

#define SERV_ADDR  "serv.socket"

int main(void)
{
    int lfd, cfd, len, size, i;
    struct sockaddr_un servaddr, cliaddr;
    char buf[4096];

    lfd = Socket(AF_UNIX, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sun_family = AF_UNIX;
    strcpy(servaddr.sun_path, SERV_ADDR);

    len = offsetof(struct sockaddr_un, sun_path) + strlen(servaddr.sun_path);     /* servaddr total len */

    unlink(SERV_ADDR);                              /* 确保bind之前serv.sock文件不存在,bind会创建该文件 */
    Bind(lfd, (struct sockaddr *)&servaddr, len);           /* 参3不能是sizeof(servaddr) */

    Listen(lfd, 20);

    printf("Accept ...\n");
    while (1) {
        len = sizeof(cliaddr);  //AF_UNIX大小+108B

        cfd = Accept(lfd, (struct sockaddr *)&cliaddr, (socklen_t *)&len);

        len -= offsetof(struct sockaddr_un, sun_path);      /* 得到文件名的长度 */
        cliaddr.sun_path[len] = '\0';                       /* 确保打印时,没有乱码出现 */

        printf("client bind filename %s\n", cliaddr.sun_path);

        while ((size = read(cfd, buf, sizeof(buf))) > 0) {
            for (i = 0; i < size; i++)
                buf[i] = toupper(buf[i]);
            write(cfd, buf, size);
        }
        close(cfd);
    }
    close(lfd);

    return 0;
}

client.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>         
#include <sys/socket.h>
#include <strings.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <stddef.h>

#include "wrap.h"

#define SERV_ADDR "serv.socket"
#define CLIE_ADDR "clie.socket"

int main(void)
{
    int  cfd, len;
    struct sockaddr_un servaddr, cliaddr;
    char buf[4096];

    cfd = Socket(AF_UNIX, SOCK_STREAM, 0);

    bzero(&cliaddr, sizeof(cliaddr));
    cliaddr.sun_family = AF_UNIX;
    strcpy(cliaddr.sun_path,CLIE_ADDR);

    len = offsetof(struct sockaddr_un, sun_path) + strlen(cliaddr.sun_path);     /* 计算客户端地址结构有效长度 */

    unlink(CLIE_ADDR);
    Bind(cfd, (struct sockaddr *)&cliaddr, len);                                 /* 客户端也需要bind, 不能依赖自动绑定*/

    
    bzero(&servaddr, sizeof(servaddr));                                          /* 构造server 地址 */
    servaddr.sun_family = AF_UNIX;
    strcpy(servaddr.sun_path, SERV_ADDR);

    len = offsetof(struct sockaddr_un, sun_path) + strlen(servaddr.sun_path);   /* 计算服务器端地址结构有效长度 */

    Connect(cfd, (struct sockaddr *)&servaddr, len);

    while (fgets(buf, sizeof(buf), stdin) != NULL) {
        write(cfd, buf, strlen(buf));
        len = read(cfd, buf, sizeof(buf));
        write(STDOUT_FILENO, buf, len);
    }

    close(cfd);

    return 0;
}

wrap.c

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>

void perr_exit(const char *s)
{
	perror(s);
	exit(-1);
}

int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)
{
	int n;

again:
	if ((n = accept(fd, sa, salenptr)) < 0) {
		if ((errno == ECONNABORTED) || (errno == EINTR))
			goto again;
		else
			perr_exit("accept error");
	}
	return n;
}

int Bind(int fd, const struct sockaddr *sa, socklen_t salen)
{
    int n;

	if ((n = bind(fd, sa, salen)) < 0)
		perr_exit("bind error");

    return n;
}

int Connect(int fd, const struct sockaddr *sa, socklen_t salen)
{
    int n;

	if ((n = connect(fd, sa, salen)) < 0)
		perr_exit("connect error");

    return n;
}

int Listen(int fd, int backlog)
{
    int n;

	if ((n = listen(fd, backlog)) < 0)
		perr_exit("listen error");

    return n;
}

int Socket(int family, int type, int protocol)
{
	int n;

	if ((n = socket(family, type, protocol)) < 0)
		perr_exit("socket error");

	return n;
}

ssize_t Read(int fd, void *ptr, size_t nbytes)
{
	ssize_t n;

again:
	if ( (n = read(fd, ptr, nbytes)) == -1) {
		if (errno == EINTR)
			goto again;
		else
			return -1;
	}
	return n;
}

ssize_t Write(int fd, const void *ptr, size_t nbytes)
{
	ssize_t n;

again:
	if ( (n = write(fd, ptr, nbytes)) == -1) {
		if (errno == EINTR)
			goto again;
		else
			return -1;
	}
	return n;
}

int Close(int fd)
{
    int n;
	if ((n = close(fd)) == -1)
		perr_exit("close error");

    return n;
}

/*参三: 应该读取的字节数*/
ssize_t Readn(int fd, void *vptr, size_t n)
{
	size_t  nleft;              //usigned int 剩余未读取的字节数
	ssize_t nread;              //int 实际读到的字节数
	char   *ptr;

	ptr = vptr;
	nleft = n;

	while (nleft > 0) {
		if ((nread = read(fd, ptr, nleft)) < 0) {
			if (errno == EINTR)
				nread = 0;
			else
				return -1;
		} else if (nread == 0)
			break;

		nleft -= nread;
		ptr += nread;
	}
	return n - nleft;
}

ssize_t Writen(int fd, const void *vptr, size_t n)
{
	size_t nleft;
	ssize_t nwritten;
	const char *ptr;

	ptr = vptr;
	nleft = n;
	while (nleft > 0) {
		if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
			if (nwritten < 0 && errno == EINTR)
				nwritten = 0;
			else
				return -1;
		}

		nleft -= nwritten;
		ptr += nwritten;
	}
	return n;
}

static ssize_t my_read(int fd, char *ptr)
{
	static int read_cnt;
	static char *read_ptr;
	static char read_buf[100];

	if (read_cnt <= 0) {
again:
		if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {
			if (errno == EINTR)
				goto again;
			return -1;
		} else if (read_cnt == 0)
			return 0;
		read_ptr = read_buf;
	}
	read_cnt--;
	*ptr = *read_ptr++;

	return 1;
}

ssize_t Readline(int fd, void *vptr, size_t maxlen)
{
	ssize_t n, rc;
	char    c, *ptr;

	ptr = vptr;
	for (n = 1; n < maxlen; n++) {
		if ( (rc = my_read(fd, &c)) == 1) {
			*ptr++ = c;
			if (c  == '\n')
				break;
		} else if (rc == 0) {
			*ptr = 0;
			return n - 1;
		} else
			return -1;
	}
	*ptr  = 0;

	return n;
}

wrap.h

#ifndef __WRAP_H_
#define __WRAP_H_

void perr_exit(const char *s);
int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr);
int Bind(int fd, const struct sockaddr *sa, socklen_t salen);
int Connect(int fd, const struct sockaddr *sa, socklen_t salen);
int Listen(int fd, int backlog);
int Socket(int family, int type, int protocol);
ssize_t Read(int fd, void *ptr, size_t nbytes);
ssize_t Write(int fd, const void *ptr, size_t nbytes);
int Close(int fd);
ssize_t Readn(int fd, void *vptr, size_t n);
ssize_t Writen(int fd, const void *vptr, size_t n);
ssize_t my_read(int fd, char *ptr);
ssize_t Readline(int fd, void *vptr, size_t maxlen);

#endif

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

网络编程7:本地套接字 的相关文章

  • Linux创建新用户和key登陆

    1 root用户身份登陆 2 新增一个用户 useradd m new user name 3 切换至新用户 su new user name 4 生成公钥和私钥 ssh keygen t rsa 一路回车 5 cd ssh 6 cat i
  • 详解C++中的ANSI与Unicode和UTF8三种字符编码基本原理与相互转换

    目录 1 概述 2 Visual Studio中的字符编码 3 ANSI窄字节编码 4 Unicode宽字节编码 5 UTF8编码 6 如何使用字符编码 7 三种字符编码之间的相互转换 xff08 附源码 xff09 7 1 ANSI编码与
  • 让ubuntu16.04开机进入命令行模式

    让ubuntu16 04开机进入命令行模式 使用Ubuntu时 xff0c 有时候我们不想开机进入桌面 xff0c 想直接进入命令行 xff0c 这样启动的比较快 xff0c 1 首先我们修改grub文件 xff0c 改为如图所示 xff1
  • centos7 开启关闭服务

    centos 7 中使用systemctl工具来管理服务程序 xff0c 包括了service和chkconfig 启动一个服务 xff1a systemctl start firewalld service 关闭一个服务 xff1a sy
  • 基于SPWM的逆变器程序应用及自制电路

    自制逆变器的电路及程序应用 设计并制作 一个简易逆变器 xff0c 其结构如图所示 逆变器进行负载试验时 xff0c 需在其输出端接负载 通常情况下 xff0c 输出电能消耗在该负载上 2 基本要求 逆变器输出端仅连接电阻性负载 xff0c
  • DNS:Bind安全配置、视图

    Bind中的安全配置 Bind支持ACL xff08 访问控制列表 xff09 功能 xff1a 主要实现把一个或多个地址归并为一个集合 xff0c 并通过一个统一的名称调用 格式 xff1a acl acl name ip ip net
  • Mozilla 修复跨平台加密库 NSS 中的严重漏洞

    聚焦源代码安全 xff0c 网罗国内外最新资讯 xff01 编译 xff1a 代码卫士 Mozilla 修复了影响跨平台网络安全服务 NSS 加密库中一个严重的内存损坏漏洞 CVE 2021 43527 NSS 可用于开发启用安全功能的客户
  • Ubuntu下将anaconda打包移植到另一个台Ubuntu下,使用ananconda的离线包库,安装包

    由于某种需求 xff0c 需要将annaconda移植到另外一台Ubuntu下 xff0c 而且另一台无法联网 xff0c 而且需要安装一些包 xff0c 使用wheel和setup安装失败后使用的这种方法 思路 xff1a 将本地的ann
  • IT66121 720P@60配置文件

    这里为IT66121 720P 64 60的配置文件 xff0c 在Linux下我是使用i2cset工具先验证再写驱动的 xff0c 所以这里我也简单记录一下 IT66121分为两个bank xff0c 一个是bank0的配置 xff0c
  • CCS编译报错 error #10234-D: unresolved symbols remain

    最近刚刚接触CCS编译器 xff0c 然后自己搭建的工程中出现了这个报错 xff1a 检查了头文件以及库都是正常的 xff0c 但就不清楚是什么原因 xff0c 最后同事帮忙解决了这个问题 xff0c 如下解决 xff1a 工程右键选择Pr
  • AM4379 关于CCS下无法正常加载程序

    最近调试4379的时候发现了个问题 xff0c 这里记录下 将boot set设置为全1模式下 xff0c 然后加载程序 xff0c 发现加载是可以正常加载 xff0c 但是运行图标是灰色的 xff08 如图 xff09 xff0c 然后我
  • S5P6818 卸载驱动时报错

    调试6818的时候 xff0c 在卸载驱动时候报了这样的错误 xff1a rmmod can 39 t change directory to 39 3 4 39 39 No such file or directory 解决办法 xff1
  • S5P6818 移植phytool报错

    下载地址 xff1a GitHub wkz phytool Linux MDIO register access 编译 xff1a make CC 61 home tronlong 6818 arm 2009q3 bin arm none
  • Ubuntu16.04 卸载vmware

    1 先查看安装的虚拟机 vmware installer l 然后会显示版本和产品名称 Product Name Product Version 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • HPS是什么?包括哪些内容?

    文章来自 xff1a http bbs eeworld com cn thread 454766 1 1 html 1 HPS Hard processor system 字面意思就是硬件处理器系统 xff0c 应该指的是和arm核相连的硬
  • Ubuntu16.04 段错误(核心已转储)的解决办法

    由于软件需求我写了个测试软件 xff0c 我定义两个u8 的buf为1280 720 8的大小 xff0c 也差不多要接近于15M 的大小了 xff0c 在语法没有错误的情况下直接报段错误 xff08 核心已转储 xff09 的错误 查找了
  • WebDriver使用指南(完整篇)

    第1章 入门 1 1 下载selenium2 0的lib包 http code google com p selenium downloads list 官方UserGuide xff1a http seleniumhq org docs
  • 关于Virtualbox使用win7鼠标卡顿问题

    工作中要用到虚拟机 xff0c 自己装了一个win7系统 xff0c 结果发现鼠标卡顿的不行 xff0c 不能流畅运行 xff0c 于是查找了很多文章 xff0c 终于解决了问题 软件版本 xff1a virtualbox7 0 解决方案
  • Ubuntu挂载分区

    1 查看本地分区 xff0c 找到你想要挂载的分区名称 sudo fdisk l 图中为以整块2T硬盘 xff0c 分为5 6 7 8 9区 xff0c 以 dev sdb7 为例 xff0c 想要将其挂载到 home plan other
  • 允许远程该计算机的其他用户

    当你想进入服务器的其他用户时 xff0c 发现通过administrator是无法直接切换用户的 xff0c 那么我们应该怎么设置呢 xff1f 解决方案 xff1a 1 右击计算机 gt 属性 gt 高级系统设置 gt 远程 xff0c

随机推荐

  • 学习Linux 编程的几本好书

    这次涉及到了具体的平台 GNU Linux Linux下开发与明显不同于Windows平台的特点 xff0c 从开发工具到项目组织 xff0c 都有较大的差距 首先声明 xff0c 在做Linux平台开发之前 xff0c 首先要熟练使用Li
  • IE8报错:Unable to modify the parent container element before the child element is closed

    xfeff xfeff 转自 xff1a http blog csdn net xinwang article details 9786447 IE8中会报 HTML Parsing Error Unable to modify the p
  • APNs 访问不到的问题

    APNs会将链接太频繁的链接视为DDos攻击 xff0c 所以链接频率不要太高 目前每5分钟连接接一次 因为使用了加密链接 xff0c 会被GFW随机阻断 看脸 看有的说建议用国外VPS 单个ip连接每次发送消息数量不要超过1000条 xf
  • 谷歌原生DocumentUI文件浏览的原理

    相信多数想了解谷歌DocumentUI设计思想的码农都会遇到障碍 xff0c 文件浏览究竟是怎么实现的 xff0c 进入DocumentUI的UI层 xff0c 不难发现 xff0c 我们是通过查询数据库获取cursor xff0c 但是查
  • linux下快速查找文件

    版权声明 xff1a 本文为博主xxt 测试开发之路的原创文章 xff0c 遵循 CC 4 0 BY SA 版权协议 xff0c 转载请附上原文出处链接和本声明 本文链接 xff1a https blog csdn net xxmonsto
  • Android 多语言对照表

    语言地区文件夹名称南非荷兰语南非values af rNA南非荷兰语纳米比亚values af rZA阿肯语加纳values ak rGH阿姆哈拉语埃塞俄比亚values am rET阿拉伯语阿拉伯联合酋长国values ar rAE阿拉伯
  • android图片轮播+点击跳转广告页面

    Android轮播网络图片 43 点击跳转广告页面 一些新手总是很头疼怎么获取网络图片的url之后让它像一些广告那样轮播起来 xff0c 点击图片之后跳转到指定网页 效果如下 在布局引用自定义控件 span class hljs pi lt
  • 用SurfaceView实现级联分层图(粗略篇)

    先看效果图 实际运行很流畅 xff0c 运行内存1M左右 最近脑抽 xff0c 想实现一个亲戚关系图谱的应用 xff0c 但始终没有找到合适的开源控件 xff0c 于是就看到一篇 利用递归算法和堆栈实现android思维导图大纲图的动态绘制
  • Android各种访问权限Permission详解

    在Android的设计中 xff0c 资源的访问或者网络连接 xff0c 要得到这些服务都需要声明其访问权限 xff0c 否则将无法正常工作 在Android中这样的权限有很多种 xff0c 这里将各类访问权限一一罗列出来 xff0c 供大
  • 桌面远程连接Ubuntu图形界面和开启ssh连接

    1 xff0c 设置Ubuntu为可被远程连接 Settings Sharing Screen Sharing Access Options设置一个远程连接的密码 连接远程是的密码 xff0c 区别于用户密码 2 xff0c 安装支持vnc
  • Android动态设置Shape

    有过一些开发经验的朋友 xff0c 在做圆角按钮的背景时可能不再需要 9的切图了 xff0c 而一般都是在drawable文件夹下面建立一个xml文件shape 其他状态不变色 或者selector 按下 选中状态变色 xff0c 但是如果
  • Android 禁止锁屏或黑屏

    转载请注明出处 xff1a http blog csdn net snailbaby soko article details 56842467 场景 xff1a 通常情况我们使用的 app 都不需要用到这个功能 但一些平板的开发就很常见了
  • Android 美团Robust热更新 使用入门

    转载请注明出处 http blog csdn net snailbaby soko article details 69524380 本篇文章已授权微信公众号 guolin blog xff08 郭霖 xff09 独家发布 Android热
  • Android 实战-版本更新(okhttp3、service、notification)

    转发请注明出处 http www jianshu com p b669940c9f3e 前言 整理功能 xff0c 把这块拿出来单独做个demo xff0c 好和大家分享交流一下 版本更新这个功能一般 app 都有实现 xff0c 而用户获
  • spark mllib源码分析之二分类逻辑回归的评价指标

    在逻辑回归分类中 xff0c 我们评价分类器好坏的主要指标有精准率 xff08 precision xff09 xff0c 召回率 xff08 recall xff09 xff0c F measure xff0c AUC等 xff0c 其中
  • AB升级之odex文件首次开机处理

    开启AB升级方案的项目 xff0c 因为很多需要升级的镜像都有两份 xff0c 所以存储空间比较浪费 为缓解此问题 xff0c 有个针对odex的优化方案 编译版本会生成两个system镜像 xff1a system img和system
  • Android Bluetooth HCI log 详解

    0 引子 对于蓝牙开发者来说 xff0c 通过HCI log可以帮助我们更好地分析问题 xff0c 理解蓝牙协议 xff0c 就好像网络开发一定要会使用Wireshark分析网络协议一样 本篇主要介绍HCI log的作用 如何抓取一份HCI
  • imx6ull开发板调试nfs环境配置+运行hello程序

    20210314 43 imx6ull开发板nfs环境配置 1 设置git邮箱和用户名 wang 64 wang virtual machine git config global user name 34 snaking616 34 wa
  • 网络编程6:线程池简介

    1 线程池相关结构体 struct threadpool t pthread mutex t lock 用于锁住本结构体 pthread mutex t thread counter 记录忙状态线程个数de琐 busy thr num pt
  • 网络编程7:本地套接字

    1 基于UDP的网络编程 1 1 TCP通信和UDP通信各自的优缺点 TCP xff1a 面向连接的 xff0c 可靠数据包传输 对于不稳定的网络层 xff0c 采取完全弥补的通信方式 丢包重传 优点 xff1a 稳定 数据流量稳定 速度稳