curl学习2

2023-11-09

代理

    什么是代理?Merrian-Webster的解释是:一个通过验证的用户扮演另一个用户。今天,代理已经被广泛的使用。许多公司提供网络代理服务器,允许员工的网络客户端访问、下载文件。代理服务器处理这些用户的请求。

    libcurl支持SOCKS和HTTP代理。使用代理,libcurl会把用户输入的URL提交给代理服务器,而不是直接根据URL去访问远程资源。

    当前版本的libcurl并不支持SOCKS代理的所有功能。

    对于HTTP代理来说,即使请求的URL不是一个合法的HTTP URL(比方你提供了一个ftp的url),它仍然会先被提交到HTTP代理。

代理选项
    CURLOPT_PROXY属性用于设置libcurl使用的代理服务器地址:

curl_easy_setopt(easy_handle, CURLOPT_PROXY, "proxy-host.com:8080");
    可以把主机名与端口号分开设置:

curl_easy_setopt(easy_handle, CURLOPT_PROXY, "proxy-host.com");
curl_easy_setopt(easy_handle, CURLOPT_PROXYPORT, "8080"); // 端口号是用字符串还是整数??
    有些代理服务器要求用户通过验证之后才允许接受其请求,此时应该先提供验证信息:

curl_easy_setopt(easy_handle, CURLOPT_PROXYUSERPWD, "user:password");
    还要告诉libcurl使用的代理类型(如果没有提供,libcurl会认为是HTTP代理):

curl_easy_setopt(easy_handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);  环境变量
     对于有些协议,libcurl会自动检测并使用一些环境变量,并根据这些环境变量来确定要使用的代理服务器。这些环境变量的名称格式一般是"[protocol]_proxy"(注意小写)。例如输入一个HTTP的URL,那么名称为"http_proxy"的环境变量就会被检测是否存在,如果存在,libcurl会使用该环境变量指定的代理。相同的规则也适用于FTP。

    这些环境变量的值的格式必须是这样的:"[protocol://][user:password@]machine[:port]"。libcurl会忽略掉[protocol://],如果没有提供端口号,libcurl使用该协议的默认端口。 

    有两个比较特殊的环境变量:'all_proxy'与'no_proxy'。如果一个URL所对应的协议,它的环境变量没有设置,那么'all_proxy'指定的代理将被使用。'no_proxy'则指定了一个不应被使用的代理主机的列表。例如:no_proxy的值是'192.168.1.10',即使存在http_proxy,它的值也是'192.168.1.10','192.168.1.10'也不会被作为代理。no_proxy=”*”表示不允许使用任何代理。

    显式地将CURLOPT_PROXY属性设置为空,可以禁止libcurl检查并使用环境变量来使用代理。

SSL和代理
    SSL为点到点通信提供安全保障。它包含一些强壮的加密措施和其他安全检测,这使得上面讲到的代理方式不适用于SSL。除非代理服务器提供专用通道,对进出该代理服务器的数据不作任何检测或禁止。通过HTTP代理服务器打开SSL连接,意味着代理服务器要直接连接到目标主机的指定端口。因为代理服务器对在专用通道上传输的数据的类型毫无所知,所以它往往会使某些机制失效,如缓存机制。许多组织只允许在443端口上创建这种类型的数据通道。

代理通道(Tunneling Through Proxy)
    正如上面讲到的,要使SSL工作必须在代理服务器创建专用数据通道,通常专用通道只被限制应用于HTTPS。通过HTTP代理在应用程序与目标之间创建一个专用数据通道,应该预防在该专有通道上执行非HTTP的操作,如进行FTP上传或执行FTP命令。代理服务器管理员应该禁止非法的操作。

    通过CURLOPT_HTTPPROXYTUNNEL属性来告诉libcurl使用代理通道:

curl_easy_setopt(easy_handle, CURLOPT_HTTPPROXYTUNNEL, 1L);
     有时候你想通过代理通道执行平常的HTTP操作,而实际上却可能使你不经过代理服务器而直接与远程主机进行交互。libcurl不会代替这种新引入的行为。

自动配置代理
    许多浏览器支持自动配置代理,例如NetScape。libcurl并不支持这些。

持久化的好处(Persistence Is The Way to Happiness)
    当需要发送多次请求时,应该重复使用easy handle。

    每次执行完curl_easy_perform,licurl会继续保持与服务器的连接。接下来的请求可以使用这个连接而不必创建新的连接(如果目标主机是同一个的话)。这样可以减少网络开销。
    即使连接被释放了,libcurl也会缓存这些连接的会话信息,这样下次再连接到目标主机上时,就可以使用这些信息,从而减少重新连接所需的时间。

    FTP连接可能会被保存较长的时间。因为客户端要与FTP服务器进行频繁的命令交互。对于有访问人数上限的FTP服务器,保持一个长连接,可以使你不需要排除等待,就直接可以与FTP服务器通信。

    libcurl会缓存DNS的解析结果。

    在今后的libcurl版本中,还会添加一些特性来提高数据通信的效率。
    每个easy handle都会保存最近使用的几个连接,以备重用。默认是5个。可以通过CURLOPT_MAXCONNECTS属性来设置保存连接的数量。

    如果你不想重用连接,将CURLOPT_FRESH_CONNECT属性设置为1。这样每次提交请求时,libcurl都会先关闭以前创建的连接,然后重新创建一个新的连接。也可以将CURLOPT_FORBID_REUSE设置为1,这样每次执行完请求,连接就会马上关闭。

libcurl使用的HTTP消息头
     当使用libcurl发送http请求时,它会自动添加一些http头。我们可以通过CURLOPT_HTTPHEADER属性手动替换、添加或删除相应的HTTP消息头。

Host
    http1.1(大部分http1.0)版本都要求客户端请求提供这个信息头。

Pragma
    "no-cache"。表示不要缓冲数据。

Accept
    "*/*"。表示允许接收任何类型的数据。

Expect
    以POST的方式向HTTP服务器提交请求时,libcurl会设置该消息头为"100-continue",它要求服务器在正式处理该请求之前,返回一个"OK"消息。如果POST的数据很小,libcurl可能不会设置该消息头。

自定义选项
    当前越来越多的协议都构建在HTTP协议之上(如:soap),这主要归功于HTTP的可靠性,以及被广泛使用的代理支持(可以穿透大部分防火墙)。 这些协议的使用方式与传统HTTP可能有很大的不同。对此,libcurl作了很好的支持。

自定义请求方式(CustomRequest)
    HTTP支持GET, HEAD或者POST提交请求。可以设置CURLOPT_CUSTOMREQUEST来设置自定义的请求方式,libcurl默认以GET方式提交请求:

curl_easy_setopt(easy_handle, CURLOPT_CUSTOMREQUEST, "MYOWNREQUEST");  修改消息头
    HTTP协议提供了消息头,请求消息头用于告诉服务器如何处理请求;响应消息头则告诉浏览器如何处理接收到的数据。在libcurl中,你可以自由的添加这些消息头:

struct curl_slist *headers=NULL; /* init to NULL is important */
headers = curl_slist_append(headers, "Hey-server-hey: how are you?");
headers = curl_slist_append(headers, "X-silly-content: yes");
/* pass our list of custom made headers */
curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers);
curl_easy_perform(easyhandle); /* transfer http */
curl_slist_free_all(headers); /* free the header list */
    对于已经存在的消息头,可以重新设置它的值:

headers = curl_slist_append(headers, "Accept: Agent-007");
headers = curl_slist_append(headers, "Host: munged.host.line");  删除消息头
    对于一个已经存在的消息头,设置它的内容为空,libcurl在发送请求时就不会同时提交该消息头:

headers = curl_slist_append(headers, "Accept:");  强制分块传输(Enforcing chunked transfer-encoding)
    (这段文字理解可能有误码)以非GET的方式提交HTTP请求时,如果设置了自定义的消息头”Transfer-Encoding:chunked”,libcurl会分块提交数据,即使要上传的数据量已经知道。在上传数据大小未知的情况下,libcurl自动采用分块上传数据。(译者注:非GET方式提交请求,提交的数据量往往比较大。)

HTTP版本
    每一次http请求,都包含一个表示当前使用http版本的消息头。libcurl默认使用HTTP 1.1。可以通过CURLOPT_HTTP_VERSION属性来设置具体的版本号:

curl_easy_setopt(easy_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);  FTP自定义命令
    并不是所以的协议都像HTTP那样,通过消息头来告诉服务器如何处理请求。对于FTP,你就要使用另外的方式来处理。

    发送自定义的命令到ftp服务器,意味着你发送的命令必须是能被ftp服务器理解的命令(FTP协议中定义的命令,参考rfc959)。

    下面是一个简单的例子,在文件传输操作操作之前删除指定文件:

headers = curl_slist_append(headers, "DELE file-to-remove");
/* pass the list of custom commands to the handle */

curl_easy_setopt(easyhandle, CURLOPT_QUOTE, headers);
// curl_easy_setopt(easyhandle, CURLOPT_POSTQUOTE, headers); // 在数据传输之后操行删除操作curl_easy_perform(easyhandle); /* transfer ftp data! */
curl_slist_free_all(headers); /* free the header list */
    FTP服务器执行命令的顺序,同这些命令被添加到列表中顺序是一致的。发往服务器的命令列表中,只要有一个命令执行失败,ftp服务器就会返回一个错误代码,此时libcurl将直接返回CURLE_QUOTE_ERROR,不再执行剩余的FTP命令。

    将CURLOPT_HEADER设置为1,libcurl获取目标文件的信息,并以HTTP消息头的样式来输出消息头。

FTP自定义CUSTOMREQUEST
    使用CURLOPT_CUSTOMREQUEST属性,可以向FTP服务器发送命令。"NLST"是ftp默认的列出文件列表的命令。 下面的代码用于列出FTP服务器上的文件列表:

int main(int argc, char **argv)
{
curl_global_init(CURL_GLOBAL_WIN32);
CURL *easy_handle = curl_easy_init();
curl_easy_setopt(easy_handle, CURLOPT_URL, ", CURLOPT_CUSTOMREQUEST, "NLST"); curl_easy_perform(easy_handle);

curl_easy_cleanup(easy_handle);
curl_global_cleanup();


return 0;
} Cookies Without Chocolate Chips
     cookie是一个键值对的集合,HTTP服务器发给客户端的cookie,客户端提交请求的时候,也会将cookie发送到服务器。服务器可以根据cookie来跟踪用户的会话信息。cookie有过期时间,超时后cookie就会失效。cookie有域名和路径限制,cookie只能发给指定域名和路径的HTTP服务器。

    cookie以消息头”Set-Cookie”的形式从HTTP服务器发送到客户端;客户端发以消息头”Cookie”的形式将Cookie提交到HTTP服务器。为了对这些东西有个直观的概念,下图是FireFox中,使用Firebug跟踪到的cookie消息头:
 

    在libcurl中,可以通过CURLOPT_COOKIE属性来设置发往服务器的cookie:

curl_easy_setopt(easy_handle, CURLOPT_COOKIE, "name1=var1; name2=var2;");
    下面的例子演示了如何使用libcurl发送cookie信息给HTTP服务器,代码非常的简单:

int main(int argc, char **argv)
{
curl_global_init(CURL_GLOBAL_WIN32);
CURL *easy_handle = curl_easy_init();


curl_easy_setopt(easy_handle, CURLOPT_URL, , CURLOPT_COOKIE, "name=JGood; address=HangZhou");


curl_easy_perform(easy_handle);


curl_easy_cleanup(easy_handle);
curl_global_cleanup();


return 0;
}
    下图是在ASP.NET Web服务器上调试时跟踪到的Cookie数据:

     在实在的应用场景中,你可能需要保存服务器发送给你的cookie,并在接下来的请求中,把这些cookie一并发往服务器。所以,可以把上次从服务器收到的所有响应头信息保存到文本文件中,当下次需要向服务器发送请求时,通过CURLOPT_COOKIEFILE属性告诉libcurl从该文件中读取cookie信息。
    设置CURLOPT_COOKIEFILE属性意味着激活libcurl的cookie parser。在cookie parser被激活之前,libcurl忽略所以之前接收到的cookie信息。cookie parser被激活之后,cookie信息将被保存内存中,在接下来的请求中,libcurl会自动将这些cookie信息添加到消息头里,你的应用程序不需要做任何事件。大多数情况下,这已经足够了。需要注意的是,通过CURLOPT_COOKIEFILE属性来激活cookie parser,给CURLOPT_COOKIEFILE属性设置的一个保存cookie信息的文本文件路径,可能并不需要在磁盘上物理存在。
    如果你需要使用NetScape或者FireFox浏览器的cookie文件,你只要用这些浏览器的cookie文件的路径来初始化CURLOPT_COOKIEFILE属性,libcurl会自动分析cookie文件,并在接下来的请求过程中使用这些cookie信息。
    libcurl甚至能够把接收到的cookie信息保存成能被Netscape/Mozilla的浏览器所识别的cookie文件。通过把这些称为cookie-jar。通过设置CURLOPT_COOKIEJAR选项,在调用curl_easy_cleanup释放easy handle的时候,所有的这些cookie信息都会保存到cookie-jar文件中。这就使得cookie信息能在不同的easy handle甚至在浏览器之间实现共享。

FTP Peculiarities We Need
    在使用FTP协议进行数据传输的时候,需要创建两个连接。第一个连接用于传输控制命令,另一个连接用于传输数据。(关于FTP的通信过程,请参考这篇文章:http://www.wangjia.net/bo-blog/post/698/)。 FTP通信需要创建两个连接这个事实往往被很多人忽略。根据第二个连接的发起方是谁,可以分为主动模式与被动模式。libcurl对此都提供了支持。libcurl默认使用被动模式,因为被动模式可以方便的穿透防火墙,NAT等问题。在被动模式下,libcurl要求ftp服务器打开一个新的端口监听,然后libcurl连接该端口用于数据传输。如果使用主动模式,程序必须告诉FTP服务器你监听的IP与端口,通过设置CURLOPT_FTPPORT属性来完成。

Headers Equal Fun
    (这段文字我理解的很模糊,请读者参考原文)有些协议提供独立于正常数据的 消息头、meta-data。正常的数据流里通常不包括 信息头和元数据。可以将CURLOPT_HEADER设置为1,使信息头、元数据也能出现在数据流中。libcurl的强大之处在于,它能够从数据流中解析出消息头,….

Post Transfer Information
[ curl_easy_getinfo ]

安全考虑
    请参考原文,此处略。

使用multi interface同时进行多项传输
     上面介绍的easy interface以同步的方式进行数据传输,curl_easy_perform会一直阻塞到数据传输完毕后返回,且一次操作只能发送一次请求,如果要同时发送多个请求,必须使用多线程。
    而multi interface以一种简单的、非阻塞的方式进行传输,它允许在一个线程中,同时提交多个相同类型的请求。 在使用multi interface之前,你应该掌握easy interface的基本使用。因为multi interface是建立在easy interface基础之上的,它只是简单的将多个easy handler添加到一个multi stack,而后同时传输而已。
    使用multi interface很简单,首先使用curl_multi_init()函数创建一个multi handler,然后使用curl_easy_init()创建一个或多个easy handler,并按照上面几章介绍的接口正常的设置相关的属性,然后通过curl_multi_add_handler将这些easy handler添加到multi handler,最后调用curl_multi_perform进行数据传输。
    curl_multi_perform是异步的、非阻塞的函数。如果它返回CURLM_CALL_MULTI_PERFORM,表示数据通信正在进行。

    通过select()来操作multi interface将会使工作变得简单(译者注:其实每个easy handler在低层就是一个socket,通过select()来管理这些socket,在有数据可读/可写/异常的时候,通知应用程序)。在调用select()函数之前,应该使用curl_multi_fdset来初始化fd_set变量。

     select()函数返回时,说明受管理的低层socket可以操作相应的操作(接收数据或发送数据,或者连接已经断开),此时应该马上调用curl_multi_perform,libcurl将会执行相应操作。使用select()时,应该设置一个较短的超时时间。在调用select()之前,造成不要忘记通过curl_multi_fdset来初始化fd_set,因为每次操作,fd_set中的文件描述符可能都不一样。

    如果你想中止multi stack中某一个easy handle的数据通信,可以调用curl_multi_remove_handle函数将其从multi stack中取出。千万另忘记释放掉easy handle(通过curl_easy_cleanup()函数)。

    当multi stack中的一个eash handle完成数据传输的时候,同时运行的传输任务数量就会减少一个。当数量降到0的时候,说明所有的数据传输已经完成。

    curl_multi_info_read用于获取当前已经完成的传输任务信息,它返回每一个easy handle的CURLcode状态码。可以根据这个状态码来判断每个easy handle传输是否成功。

    下面的例子,演示了如何使用multi interface进行网页抓取:

int main(int argc, char **argv)
{
// 初始化
curl_global_init(CURL_GLOBAL_WIN32);
CURLM *multi_handle = NULL;
CURL *easy_handle1 = NULL;
CURL *easy_handle2 = NULL;

extern size_t save_sina_page(void *buffer, size_t size, size_t count, void *user_p);
extern size_t save_sohu_page(void *buffer, size_t size, size_t count, void *user_p);
FILE *fp_sina = fopen("sina.html", "ab+");
FILE *fp_sohu = fopen("sohu.html", "ab+");

multi_handle = curl_multi_init();

// 设置easy handle
easy_handle1 = curl_easy_init();
curl_easy_setopt(easy_handle1, CURLOPT_URL, "http://www.sina.com.cn");
curl_easy_setopt(easy_handle1, CURLOPT_WRITEFUNCTION, &save_sina_page);
curl_easy_setopt(easy_handle1, CURLOPT_WRITEDATA, fp_sina);

easy_handle2 = curl_easy_init();
curl_easy_setopt(easy_handle2, CURLOPT_URL, "http://www.sohu.com");
curl_easy_setopt(easy_handle2, CURLOPT_WRITEFUNCTION, &save_sohu_page);
curl_easy_setopt(easy_handle2, CURLOPT_WRITEDATA, fp_sohu);

// 添加到multi stack
curl_multi_add_handle(multi_handle, easy_handle1);
curl_multi_add_handle(multi_handle, easy_handle2);

//
int running_handle_count;
while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &running_handle_count))
{
cout << running_handle_count << endl;
}

while (running_handle_count)
{
timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;

int max_fd;
fd_set fd_read;
fd_set fd_write;
fd_set fd_except;

FD_ZERO(&fd_read);
FD_ZERO(&fd_write);
FD_ZERO(&fd_except);

curl_multi_fdset(multi_handle, &fd_read, &fd_write, &fd_except, &max_fd);
int return_code = select(max_fd + 1, &fd_read, &fd_write, &fd_except, &tv);
if (SOCKET_ERROR == return_code)
{
cerr << "select error." << endl;
break;
}
else
{
while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &running_handle_count))
{
cout << running_handle_count << endl;
}
}
}

// 释放资源
fclose(fp_sina);
fclose(fp_sohu);
curl_easy_cleanup(easy_handle1);
curl_easy_cleanup(easy_handle2);
curl_multi_cleanup(multi_handle);
curl_global_cleanup();

return 0;
}

size_t save_sina_page(void *buffer, size_t size, size_t count, void *user_p)
{
return fwrite(buffer, size, count, (FILE *)user_p);
}

size_t save_sohu_page(void *buffer, size_t size, size_t count, void *user_p)
{
return fwrite(buffer, size, count, (FILE *)user_p);
} SSL, 证书,其他技巧
[ seeding, passwords, keys, certificates, ENGINE, ca certs ]

在easy handler之间共享数据

 

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

curl学习2 的相关文章

  • 如何增加ofstream的缓冲区大小

    我想增加 C 程序的缓冲区大小 以便它不会过于频繁地写入 默认缓冲区是 8192 字节 我尝试使用 pubsetbuf 将其增加到 200K 原始代码 ofstream fq fastq1 cstr ios out fastq1 is a
  • 为什么这个实现方法看不到它的同级方法? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我有一个实现接口的类 public class SQLiteHHSDBUtils IHHSDBUtils void IHHSDBUtils
  • 使用 FileInputStream 时如何确定理想的缓冲区大小?

    我有一个从文件创建 MessageDigest 哈希 的方法 我需要对很多文件 gt 100 000 执行此操作 用于读取文件的缓冲区应该设置多大才能最大限度地提高性能 大多数人都熟悉基本代码 为了以防万一 我将在这里重复一遍 Messag
  • 为什么应该首选 Java 类的接口?

    PMD https pmd github io 将举报以下违规行为 ArrayList list new ArrayList 违规行为是 避免使用 ArrayList 等实现类型 而是使用接口 以下行将纠正违规行为 List list ne
  • Java中接口作为方法参数

    前几天去面试 被问到了这样的问题 问 反转链表 给出以下代码 public class ReverseList interface NodeList int getItem NodeList nextNode void reverse No
  • 防止在派生类中调用基类实现的接口方法 C#

    是否可以在基类中实现接口并允许在第一个派生类级别调用 覆盖已实现的方法 但阻止从任何进一步的派生类调用它 public interface IInterfaceSample bool Test public class Base IInte
  • 为什么不直接使用 DateTime.Now 呢?

    最近一直在努力学习接口方面的知识 我看到了这段代码 但无法理解为什么你不直接使用DateTime Now在其自己的 我不确定为什么这个界面很有用 有人可以解释一下吗 这本书的作者试图解释 但我不太明白如何按照他们所说的方式实现它 程序员是否
  • 多个 WCF 服务实现相同的服务契约接口

    多个wcf服务是否可以实现同一个服务契约接口 我想要做的是允许测试服务与真实服务互换 并指定在配置文件中使用哪个服务 例如 ServiceContract public interface IUselessService Operation
  • 了解 C# 中的协变和逆变接口

    我在一本有关 C 的教科书中遇到过这些内容 但我很难理解它们 可能是由于缺乏上下文 对于它们是什么以及它们有什么用处 是否有一个很好的简洁解释 编辑以澄清 协变接口 interface IBibble
  • 比较:接口方法、虚方法、抽象方法

    它们各自的优点和缺点是什么 接口方法 虚拟方法 抽象方法 什么时候应该选择什么 做出这一决定时应牢记哪些要点 虚拟和抽象几乎是一样的 虚方法在基类中有一个实现 可以选择重写 而抽象方法则没有 并且must在子类中被覆盖 否则它们是相同的 在
  • 接口的隐式和显式实现

    在进行升级时 我碰巧遇到了这样的代码 interface ICustomization IMMColumnsDefinition GetColumnsDefinition class Customization ICustomization
  • OpenGL:VAO 和 VBO 对于大型多边形渲染任务是否实用?

    如果您想渲染一次在视锥体中包含数千个多边形的大型景观 并且用户的视点不断变化 那么使用 VAO 或 VBO 是否实用 我的意思是 每次玩家的位置或摄像机旋转发生变化时 您都必须重新计算顶点数据 以便正确剔除不再可见的任何顶点或场景 以保持良
  • python 3+ 的缓冲函数

    我试图使用 vtk show 打开一个 vtk 窗口 但是每次我这样做时 我的 Ipython 控制台都会崩溃 显然这是因为 Ipython 无法显示外部窗口 而这正是 vtk show 所做的 我在谷歌上搜索了一个解决方案 但它是为 py
  • 枚举

    我试图拥有一组扩展通用接口的枚举 例如 interface Fooable void someCommonMethod enum E1 implements Fooable some enumuerations and a definiti
  • 如何在 Emacs shell 缓冲区中获得对“✖”等的支持?

    我正在运行一个进程 如果出现错误 则输出字符 如 Unicode 中定义 但是 如果在 Emacs shell 缓冲区 GNU Emacs 的 Aquamacs 发行版 中运行该进程 我根本看不到错误 使用 braeburn aquamac
  • Java抽象类实现了一个接口,两者具有相同的方法

    在看一些OOP资料时 我想到了这个让我有点困惑的问题 考虑具有以下接口 抽象类和具体类 package one public interface A void doStuff package one public abstract clas
  • Java:接口可以包含其中定义的常量变量吗?

    我可以创建吗public static final接口中的变量 我可以保留这些文件中定义的一些常见常量值吗 是的你可以 public interface Constants public static final int ZERO 0 然而
  • 类型擦除露出丑陋的头,如何规避?

    所以我有这个界面 public interface EventHandler
  • 如何将一个接口方法的返回类型定义为另一个接口?

    我对接口和抽象类很陌生 我想创建几个接口来定义购物车系统对象的核心方法和变量 然后我想创建实现核心功能的抽象类 这个想法是 其他类可以以稍微不同的方式针对不同的项目使用它们 这是我的 精简的 界面 public interface ICar
  • java中什么是静态接口?

    我正在阅读Map Entry界面 当我注意到它是一个static界面 我不太明白什么是静态接口 它与常规接口有什么不同 public static interface Map Entry

随机推荐

  • Python的下载和安装教程

    今天学习python以及pycharm的下载和安装 参考了好几个博客 在此总结一下安装过程 注意 在这里说明一下 如果要用pycharm进行python的开发 是要分别下载pycharm和python的 不要只安装pycharm就结束了 一
  • 命令提示符的使用及运行Java程序

    常用的命令提示符 dir 列出当前目录下的文件以及文件夹 director md 创建目录 make director rd 删除目录 cd 进入指定目录 cd 退回到上一级目录 cd 退回到根目录 del 删除文件 del txt可以将所
  • c++11std::thread扩展

    最近 整理一下学习c 的文章 看到一篇文章 其中提到了thread local和std future 觉得这两东西很有趣 于是网上搜了一些资料 觉得很有帮助 希望可以对大家学习c 线程有所帮助 http www cnblogs com ha
  • 嵌入式设备文件系统构建——增加用户登录功能

    1 修改inittab文件 first run the system script file sysinit etc init d rcS 进入命令行 askfirst bin sh 添加执行登录验证 sysinit bin login c
  • 【毕设教程】随机森林算法

    文章目录 0 前言 1 什么是随机森林 2 随机森林构造流程 3 随机森林的优缺点 3 1 优点 3 2 缺点 3 3 随机森林算法实现 4 最后 0 前言 Hi 大家好 这里是丹成学长的毕设系列文章 对毕设有任何疑问都可以问学长哦 这两年
  • Firebug调试经验与技巧

    昨天网站出问题了1 为了调试cookie 特别找了关于firebug里面如何调试cookie的文章 觉得这篇不错 保留下来备份 Firebug调试经验与技巧 2009 03 13 15 22 16 转自 http blog sina com
  • redis,mysql,elasticsearch,hbase,hive对比区别,该如何选择

    几种数据库对比如下 redis mysql elasticsearch hbase hive 容量 容量扩展 低 中 大 海量 海量 查询时效性 极高 中等 较高 较高 低 查询灵活性 较差 非常好 较好 较差 非常好 写入速度 极快 中等
  • U3D通过按钮点击实现场景切换

    1 新建UI 选择button选项 新建button 2 file gt Build settings gt Add Open Scenes 把你当前场景添加进去 gt 把你想要切换的场景拖拽上去 3 新建一个空对象 挂载一个scenech
  • org.apache.http.ConnectionClosedException Premature end of Content-Length delimited message body

    最近生产环境报了这个系统异常 org apache http ConnectionClosedException Premature end of Content Length delimited message body expected
  • CANOE入门:DBC创建和编辑

    目录 dbc文件创建步骤 创建一个DBC数据库文件 创建网络节点Network nodes 创建Message 创建信号Signal 创建Signals用到的数值表Value Tables 将Value Tables关联到Signals 将
  • I/O error on GET request for "http://user-service/hi": user-service; nested exception is java.net.Un

    一 场景重现 最近闲暇时间打算系统学习下SpringCloud系统教程 毕竟最近微服务也挺火的 于是网上找了一个大牛的博客跟着一起学习 史上最简单的SpringCloud教程 一直跟着模仿构建SpringCloud一直也没出什么问题 直到在
  • Pgsql与Oracle语法差异(SQL迁移记录)

    oracle 数据库中没有limit关键字 LIMIT 1 替换为 rownum 1 select from table where rownum 1 输出1条 oracle 自增序列使用 sequence PGSQL 自增序列可用 ser
  • jquery笔记回顾

    jquery 1 jquery概念 js框架封装的原生的js代码 2 jquery版本区别及使用 jquery xxx js 有排版 体积大 jquery xxx min js 无排版 体积小 3 jquery与原生js对象进行互转 jqu
  • hk-bc.xyz forum.php,www.xavdz.com

    Domain Name XAVDZ COM Registry Domain ID 1838157110 DOMAIN COM VRSN Registrar WHOIS Server whois enom com Registrar URL
  • Kafka面试题

    Kafka核心总控制器Controller是什么 在Kafka集群中会有一个或者多个broker 其中有一个broker会被选举为控制器 Kafka Controller 它负责管理整个集群中所有分区和副本的状态 Controller选举机
  • 使用代理同步Chromium代码的心得

    先参看 http www chromium org developers how tos build instructions windows 非常坑爹 谷歌获取chromium源码的方式又变了 从chromium39 0 2313 2之后
  • poj 2155 Matrix

    Problem poj org problem id 2155 vjudge net contest 146952 problem A Meaning 一个 N N 的矩阵 A 初始时全部值为 0 有两种操作 1 C x1 y1 x2 y2
  • 电机驱动板发烫严重怎么办?一份大厂PCB布局指南参考

    作者 Pete Millett Technical Marketing Engineer Monolithic Power Systems 翻译 Toffee Jia 来源 MPS 电机驱动 IC 传递大量电流的同时也耗散了大量电能 通常
  • java远程连接linux并发送命令,两种方案比较Jsch与ganymed-ssh2

    通过Jsch连接 step 1引入jar包
  • curl学习2

    代理 什么是代理 Merrian Webster的解释是 一个通过验证的用户扮演另一个用户 今天 代理已经被广泛的使用 许多公司提供网络代理服务器 允许员工的网络客户端访问 下载文件 代理服务器处理这些用户的请求 libcurl支持SOCK