如何建立socket5代理服务器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何建立socket5代理服务器相关的知识,希望对你有一定的参考价值。
参考技术A (1)设置用户验证和记账功能,可按用户进行记账,没有登记的用户无权通过代理服务器访问Internet网。并对用户的访问时间、访问地点、信息流量进行统计。(2)对用户进行分级管理,设置不同用户的访问权限,对外界或内部的Internet地址进行过滤,设置不同的访问权限。
(3)增加缓冲器(Cache),提高访问速度,对经常访问的地址创建缓冲区,大大提高热门站点的访问效率。通常代理服务器都设置一个较大的硬盘缓冲区(可能高达几个GB或更大),当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,以提高访问速度。本回答被提问者和网友采纳
在使用C语言的socket编程中,如何设置服务器接受客户端建立连接的时间限制?
【中文标题】在使用C语言的socket编程中,如何设置服务器接受客户端建立连接的时间限制?【英文标题】:In socket programming using C language, how to set time limit on server for accepting client to establish connection? 【发布时间】:2021-01-23 04:05:10 【问题描述】:我正在开发一个涉及 1 个客户端和 1 个服务器的应用程序。
我希望服务器只侦听 5 秒钟的连接。如果客户端未尝试建立连接,则服务器应停止侦听并返回错误消息。如果客户端尝试建立连接,那么服务器应该接受连接。
如果客户端没有尝试建立连接,服务器会一直监听。我希望服务器只监听 5 秒,如何实现?
这是服务器端的输出 - 服务器一直在等待客户端:
void reception()
int sockfd, connfd, len;
struct sockaddr_in servaddr, cli;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
printf("socket creation failed...\n");
exit(0);
else
printf("Socket successfully created..\n");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0)
printf("socket bind failed...\n");
exit(0);
else
printf("Socket successfully binded..\n");
if ((listen(sockfd, 5)) != 0)
printf("Listen failed...\n");
exit(0);
else
printf("Server listening..\n");
len = sizeof(cli);
connfd = accept(sockfd, (SA*)&cli, &len);
/*
Some function should be added at this point to
stop the server from listening after 5 seconds
*/
if (connfd < 0)
printf("server acccept failed...\n");
exit(0);
else
printf("server acccept the client...\n");
receive(connfd);
close(sockfd);
【问题讨论】:
【参考方案1】:您在阻塞模式下使用侦听套接字,因此accept()
将阻塞调用线程,直到客户端连接。要使用超时,请先调用 select()
或 (e)poll()
以等待侦听套接字进入可读状态,指示连接处于挂起状态,然后再调用 accept()
。
例如:
...
fd_set rds;
FD_ZERO(&rds);
FD_SET(sockfd, &rds);
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
int res;
if ((res = select(sockfd+1, &rds, NULL, NULL, &timeout)) <= 0)
if (res < 0)
printf("select failed...\n");
else
printf("Time out...\n");
exit(0);
connfd = accept(sockfd, (SA*)&cli, &len);
...
...
struct pollfd pfd;
pfd.fd = sockfd;
pfd.events = POLLIN;
pfd.revents = 0;
int res;
if ((res = poll(&pfd, 1, 5000)) <= 0)
if (res < 0)
printf("poll failed...\n");
else
printf("Time out...\n");
exit(0);
connfd = accept(sockfd, (SA*)&cli, &len);
...
int epfd = epoll_create(1);
if (epfd < 0)
printf("epoll_create failed...\n");
exit(0);
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = sockfd;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev) < 0)
printf("epoll_ctl failed...\n");
exit(0);
struct epoll_event event;
int res;
if ((res = epoll_wait(epfd, &event, 1, 5000)) <= 0)
if (res < 0)
printf("epoll_ctl failed...\n");
else
printf("Time out...\n");
exit(0);
close(epfd);
connfd = accept(sockfd, (SA*)&cli, &len);
...
无论哪种方式,请注意这些场景会产生非常小的竞争条件。如果客户端在调用accept()
之前连接然后断开,accept()
可能阻塞等待新的挂起连接,或者它可能返回一个在后续 I/O 调用中失败的有效文件描述符。没有任何一种方式可以保证。
要解决竞争条件,您可以:
将监听套接字置于非阻塞模式。如果select()
报告监听套接字有一个挂起的连接,但accept()
无法立即接受,那么您可以采取相应的行动。
在阻塞模式下在侦听套接字上使用accept()
,就像您最初一样,但使用alert()
来安排accept()
如果它在5 秒内没有退出则被中断。示例见this answer。
【讨论】:
以上是关于如何建立socket5代理服务器的主要内容,如果未能解决你的问题,请参考以下文章
C# HttpWebRequest 如何实现SOCKET5代理