- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我使用 socket 在 linux 上用 c 开发了一个服务器。
服务器运行正常。如果我从我的网络浏览器向服务器发出请求,服务器会毫无问题地响应请求。
但我在捕获流量(使用 wireshark)时指出,我的服务器有时(很少)返回一个 tcp 错误 [RST,ACK]。
这里在wireshark中显示的tcp错误包之后
192.168.1.211是我的服务器地址
我检查了“follow tcp stream”,我发现它包含 2 个请求(来自网络浏览器)。我认为它应该只包含给定套接字中的一个请求。我说得对吗?
在跟随 tcp 流之后:
我不知道这是否是一个正常错误并且可能发生在 TCP 堆栈中?还是我的代码有问题?
代码:
static void http_cr_new_client(int client, bool service_available)
{
FILE *fp;
char buffer[BUFSIZ];
int8_t auth_status = 0;
fp = fdopen(client, "r+");
while (fgets(buffer, sizeof(buffer), fp)) {
if (!strncasecmp(buffer, "Authorization: Digest ", strlen("Authorization: Digest "))) {
char *username = conf.cpe_userid;
char *password = conf.cpe_passwd;
if (!username || !password) {
// if we dont have username or password configured proceed with connecting to ACS
service_available = false;
goto http_end;
}
if (http_digest_auth_check("GET", "/", buffer + strlen("Authorization: Digest "), REALM, username, password, 300) == MHD_YES)
auth_status = 1;
else
auth_status = 0;
}
if (buffer[0] == '\r' || buffer[0] == '\n') {
/* end of http request (empty line) */
goto http_end;
}
}
if(!service_available) {
goto http_end;
}
http_error:
/* here we are because of an error, e.g. timeout */
goto http_done;
http_end:
if (!service_available) {
MY_LOG (INFO,"Receive Connection Request: Return 503 Service Unavailable");
fputs("HTTP/1.1 503 Service Unavailable\r\n", fp);
fputs("Connection: close\r\n", fp);
} else if (auth_status) {
MY_LOG (INFO,"Receive Connection Request: success authentication");
fputs("HTTP/1.1 200 OK\r\n", fp);
fputs("Content-Length: 0\r\n", fp);
http_success_cr();
} else {
MY_LOG (INFO,"Receive Connection Request: Return 401 Unauthorized");
fputs("HTTP/1.1 401 Unauthorized\r\n", fp);
fputs("Connection: close\r\n", fp);
http_digest_auth_fail_response(fp, "GET", "/", REALM, OPAQUE);
fputs("\r\n", fp);
}
fputs("\r\n", fp);
http_done:
fclose(fp);
close(client);
}
void http_server_init(void)
{
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;
static int cr_request = 0;
static time_t restrict_start_time = 0;
time_t current_time;
bool service_available;
for(;;) {
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
MY_LOG (ERROR,"Could not open server socket for Connection Requests");
sleep(1);
continue;
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(conf.connection_request_port);
/* enable SO_REUSEADDR */
int reusaddr = 1;
if (setsockopt(socket_desc, SOL_SOCKET, SO_REUSEADDR, &reusaddr, sizeof(int)) < 0) {
MY_LOG (WARNING,"setsockopt(SO_REUSEADDR) failed");
}
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
MY_LOG (ERROR,"Could not bind server socket for Connection Requests");
sleep(1);
continue;
}
break;
}
MY_LOG (INFO,"Connection Request server initiated");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
c = sizeof(struct sockaddr_in);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
current_time = time(NULL);
service_available = true;
if ((restrict_start_time==0) ||
((current_time-restrict_start_time) > CONNECTION_REQUEST_RESTRICT_PERIOD))
{
restrict_start_time = current_time;
cr_request = 1;
}
else
{
cr_request++;
if (cr_request > 70)
{
restrict_start_time = current_time;
service_available = false;
}
}
http_cr_new_client(client_sock, service_available);
}
if (client_sock < 0)
{
MY_LOG(ERROR,"Could not accept connections for Connection Requests!");
return;
}
}
注意:我使用 pthread_create()
最佳答案
看起来您希望在您的代码中只处理一个请求。 HTTP 协议(protocol)在 1.1 版本中添加了持久连接,允许同一个 TCP 套接字被重复用于 1 个以上的请求。
对于持久连接,客户端(您的浏览器)将发送“Connection: keep-alive” header 以表明它支持持久连接(您的浏览器支持)。然后服务器可以用相同的方式回复,或者使用“Connection: close”来表示它不支持持久连接,因此客户端应该关闭当前套接字并为后续请求打开一个新套接字。
在你的例子中,浏览器打开一个套接字连接,发送一个请求并告诉你它支持持久连接。然后您的服务器发送响应并关闭连接。浏览器尝试通过同一连接发送第二个请求但失败,导致出现您看到的错误。
您可以修改您的代码以保持套接字打开并处理多个请求,或者添加“连接:关闭”以告诉客户端您不支持持久连接。
关于c++ - 套接字服务器为某些请求返回 tcp 错误 [RST, ACK],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26125238/
使用普通的 grep 命令,有一个 --exclude 选项(详细介绍如下: Use grep --exclude/--include syntax to not grep through certa
我有 ubuntu 14.04。并使用 ack-grep 2.12 在目录内递归搜索文件中的文本 我想设置 ack-grep 选项 特定于目录 ~/workspace/project/ 这样当我在路径
我们不理解这种 TCP 行为表明 redhat linux 5 TCP 堆栈(HTTP 服务器,这是此转储的来源)收到 SYN 的 ACK,ACK 但继续忽略它并重复重复的 SYN,ACK 5次。最后
我不确定它的用途,但我正在处理的代码有一堆名为“save.d”的文件夹,看起来它们用于某种版本控制(我们也有 . svn 文件夹)。 如何更新我的 .ackrc 文件以默认忽略这些目录? 我的 .ac
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭去年。 Improve th
我已经针对运行在 Ubuntu 14.04.3 LTS (3.13.0-71-generic x86_64) 上的 OpenSSL 1.0.2e 编译了 nginx 1.9.7。我可以毫无问题地使用浏
我有添加新的 ack-grep 文件类型的语法: $ ack-grep --type-add=min=.min.js,.min.css --help types | grep min --[n
我想在任何名为 search-this-one.html 的文件中搜索字符串“my-search-string” 在我当前工作目录的所有子目录中。 我想要包含此字符串的文件的完整路径列表。有数百个名为
我正在使用 ack.pl 工具来搜索文件中的字符串或 IP ack.pl 的官方网站是 - http://beyondgrep.com/documentation/ ack.pl CLI 示例(想在/
如果您正在编写一个基本的 python TCP 服务器和客户端,您需要自己添加 SYN、SYN ACK 和 ACK 响应,还是由套接字模块处理? 如果需要自己写,会这么简单吗? 客户: #set up
[FIN, ACK]、[RST]和[RST, ACK]是什么原因,如何避免? 是否是由于 SO 的 TCP 参数之间存在某种不匹配?服务器在 TCP/IP 连接中回复 [FIN, ACK] 是什么意思
我使用 Vim 插件 ack.vim ,但我不明白为什么命令是带有大写“A”的 :Ack (按住 shift 有点烦人)。 是否可以将其重新映射到 :ack ? 最佳答案 内置命令以小写字符开头,自定
我有一个文件导致 Ack 2.0 报告“权限被拒绝”错误,所以我一直试图让它忽略该文件。 我已经在我的 ackrc 中尝试了以下内容 --type-set=lockfile:match:/NameOf
我有一个文件导致 Ack 2.0 报告“权限被拒绝”错误,所以我一直试图让它忽略该文件。 我已经在我的 ackrc 中尝试了以下内容 --type-set=lockfile:match:/NameOf
我尝试了可能的组合并在互联网上进行了搜索,但无法完成这项工作,错误是: Error: Unexpected ACK received for message-id 如果有人能指出以下代码中是否存在一些
在用 Linux C 编写的 tcp 程序中我想关闭一个 tcp 连接我使用了close(sockfd)我注意到此函数将向另一个对等方发起 FIN/ACK 数据包但是如果另一个对等点由于网络问题或 t
我已经构建了一个 c 函数,该函数应该通过 stomp 库从 ActiveMQ 读取。此代码正在读取收据之前的附加消息(这是我所期望的)。请告知为什么我的 RECEIPT 帧没有在第二个 MESSAG
我正在使用这样的 ack:ack-grep assets\\. (在 Ubuntu 上) 但是,我想排除不以“ Assets ”开头的结果。例如:网站 Assets 。 到目前为止,我已经尝试过 ac
如何使用ack搜索特定文件类型的文件。 例如 ack -f .scss blah acl -f .rb blah 显然上述方法不起作用,但是如何使用ack来做到这一点? 最佳答案 为此使用--type
每次我尝试在ack中添加类型似乎都失败了,即在ack中添加类型(log) ack --type-set log:ext:log ack: No regular expression found. 或者
我是一名优秀的程序员,十分优秀!