我試圖使用C程序從Google Server(以HTTP GET請求的形式)接受OAuth 2授權碼。如果我嘗試閱讀使用recv(),則會引發錯誤,傳輸端點未連接。這只是在accept()調用後我收到一個非負整數後。我已經嘗試使用Java和Netcat實用程序相同,都適合我。在調用close之前關閉套接字但不關閉
這是代碼。
#include<stdio.h>
#include<string.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#include<sys/select.h>
#include<fcntl.h>
#include<errno.h>
void *send_authcode_request(void *sockaddr_ptr);
int main() {
char *bind_addr = "127.0.0.1";
char *errmsg = (char *) malloc(1024);
short int port = 0;
setvbuf(stdout, NULL, _IONBF, 0);
struct sockaddr_in local_addr;
struct sockaddr_in client_addr;
local_addr.sin_family = AF_INET;
local_addr.sin_port = port;
inet_aton(bind_addr, &(local_addr.sin_addr));
memset(&(local_addr.sin_zero), '\0', 8);
int sock_id = socket(AF_INET, SOCK_STREAM, 0);
/*fcntl(sock_id, F_SETFL, O_NONBLOCK);*/
if (bind(sock_id, (struct sockaddr*) &local_addr, sizeof(struct sockaddr)) == -1) {
sprintf(errmsg, "Cannot bind socket to the port #%d", port);
perror(errmsg);
return -1;
}
if (listen(sock_id, 20) == -1) {
sprintf(errmsg, "Cannot listen to connections on the socket");
perror(errmsg);
return -1;
}
int sin_size = sizeof(struct sockaddr_in);
if(getsockname(sock_id, (struct sockaddr *) &local_addr, &sin_size) == -1) {
sprintf(errmsg, "Unable to get the current address of the socket");
perror(errmsg);
return -1;
}
printf("\n Port no after binding #%d\n", ntohs(local_addr.sin_port));
pthread_t authcode_req_thread;
pthread_create(&authcode_req_thread, NULL, send_authcode_request, (void *) &local_addr);
fd_set read_fs;
FD_ZERO(&read_fs);
FD_SET(sock_id, &read_fs);
long accept_timeout = 60*10;
struct timeval tv;
tv.tv_sec = accept_timeout;
tv.tv_usec = 0;
char auth_code_info[1024];
if (select(sock_id+1, &read_fs, NULL, NULL, &tv) > 0) {
/*if(accept4(sock_id, (struct sockaddr *) &client_addr, &sin_size, SOCK_NONBLOCK) == -1) {*/
if(accept(sock_id, (struct sockaddr *) &client_addr, &sin_size) >= 0) {
/* Accept auth code */
int bytesread;
if ((bytesread = recv(sock_id, auth_code_info, 1023, 0)) == -1) {
perror(errmsg);
return -1;
}
printf("\n%s\n", auth_code_info);
char *reply = "Done! You can now close the window";
send(sock_id, reply, strlen(reply), 0);
} else {
sprintf(errmsg, "No client connected within timeout of %ld seconds", accept_timeout);
perror(errmsg);
return -1;
}
} else {
sprintf(errmsg, "No client connected within timeout of %ld seconds", accept_timeout);
perror(errmsg);
return -1;
}
close(sock_id);
printf("\n");
return 0;
}
void *send_authcode_request(void *ptr) {
char *scope = "https://www.googleapis.com/auth/drive";
char *client_id = "1098482466406-c3h15ld90l03s0pl4rm7qq54fcb49t78.apps.googleusercontent.com";
const char *temp_authcode_uri = "xdg-open \"https://accounts.google.com/o/oauth2/v2/auth?scope=%s&redirect_uri=http://127.0.0.1:%d&response_type=code&client_id=%s\"";
struct sockaddr_in *socket_address = (struct sockaddr_in *) ptr;
int max_authcode_uri_len = strlen(temp_authcode_uri) + strlen(client_id) + strlen(scope);
char *authcode_uri = (char *) malloc(max_authcode_uri_len);
sprintf(authcode_uri, temp_authcode_uri, scope, ntohs(socket_address->sin_port), client_id);
printf("\n%s\n", authcode_uri);
system(authcode_uri);
}
然而,當我聽使用netcat的相同的端口,它顯示來自瀏覽器的HTTP請求。所以我使用Wireshark跟蹤了端口的TCP流量,發現一個流量與我在使用netcat時獲得的流量不同。
我的程序
No. Time Source Destination Protocol Length Info
1 0.000000000 127.0.0.1 127.0.0.1 TCP 74 48234 → 49927 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7268636 TSecr=0 WS=128
2 0.000010715 127.0.0.1 127.0.0.1 TCP 74 49927 → 48234 [SYN, ACK] Seq=0 Ack=1 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7268636 TSecr=7268636 WS=128
3 0.000020978 127.0.0.1 127.0.0.1 TCP 66 48234 → 49927 [ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=7268636 TSecr=7268636
4 0.000059901 127.0.0.1 127.0.0.1 TCP 74 48236 → 49927 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7268636 TSecr=0 WS=128
5 0.000064624 127.0.0.1 127.0.0.1 TCP 74 49927 → 48236 [SYN, ACK] Seq=0 Ack=1 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7268636 TSecr=7268636 WS=128
6 0.000070536 127.0.0.1 127.0.0.1 TCP 66 48236 → 49927 [ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=7268636 TSecr=7268636
7 0.000384302 127.0.0.1 127.0.0.1 TCP 66 49927 → 48234 [FIN, ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=7268636 TSecr=7268636
8 0.000412860 127.0.0.1 127.0.0.1 TCP 66 49927 → 48236 [RST, ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=7268636 TSecr=7268636
9 0.000997709 127.0.0.1 127.0.0.1 TCP 66 48234 → 49927 [FIN, ACK] Seq=1 Ack=2 Win=43776 Len=0 TSval=7268637 TSecr=7268636
10 0.000974316 127.0.0.1 127.0.0.1 TCP 66 [TCP Keep-Alive] 48234 → 49927 [ACK] Seq=1 Ack=2 Win=43776 Len=0 TSval=7268637 TSecr=7268636
11 0.001005630 127.0.0.1 127.0.0.1 TCP 66 49927 → 48234 [ACK] Seq=2 Ack=2 Win=43776 Len=0 TSval=7268637 TSecr=7268637
12 0.001047174 127.0.0.1 127.0.0.1 TCP 74 48238 → 49927 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7268637 TSecr=0 WS=128
13 0.001051855 127.0.0.1 127.0.0.1 TCP 54 49927 → 48238 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
14 0.237652758 127.0.0.1 127.0.0.1 TCP 74 48240 → 49927 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7268696 TSecr=0 WS=128
15 0.237664760 127.0.0.1 127.0.0.1 TCP 54 49927 → 48240 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
16 5.243733213 127.0.0.1 127.0.0.1 TCP 74 48242 → 49927 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7269947 TSecr=0 WS=128
17 5.243751969 127.0.0.1 127.0.0.1 TCP 54 49927 → 48242 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
使用netcat的時候
使用的netcat
,我得到包含身份驗證令牌所需要的HTTP GET請求。
No. Time Source Destination Protocol Length Info
1 0.000000000 127.0.0.1 127.0.0.1 TCP 74 45064 → 2807 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7233868 TSecr=0 WS=128
2 0.000008155 127.0.0.1 127.0.0.1 TCP 74 2807 → 45064 [SYN, ACK] Seq=0 Ack=1 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7233868 TSecr=7233868 WS=128
3 0.000015895 127.0.0.1 127.0.0.1 TCP 66 45064 → 2807 [ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=7233868 TSecr=7233868
4 0.000043941 127.0.0.1 127.0.0.1 TCP 74 45066 → 2807 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7233868 TSecr=0 WS=128
5 0.000047566 127.0.0.1 127.0.0.1 TCP 74 2807 → 45066 [SYN, ACK] Seq=0 Ack=1 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7233868 TSecr=7233868 WS=128
6 0.000050911 127.0.0.1 127.0.0.1 TCP 66 45066 → 2807 [ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=7233868 TSecr=7233868
7 0.000074583 127.0.0.1 127.0.0.1 TCP 66 2807 → 45066 [RST, ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=7233868 TSecr=7233868
8 0.000833585 127.0.0.1 127.0.0.1 HTTP 654 GET /?code=4/zuPKCQlOvIcJq5gAvPRGLQdkiICNzOmAQUAx9apK5go HTTP/1.1
9 0.000841060 127.0.0.1 127.0.0.1 TCP 66 2807 → 45064 [ACK] Seq=1 Ack=589 Win=44928 Len=0 TSval=7233868 TSecr=7233868
10 45.005118503 127.0.0.1 127.0.0.1 TCP 66 [TCP Keep-Alive] 45064 → 2807 [ACK] Seq=588 Ack=1 Win=43776 Len=0 TSval=7245120 TSecr=7233868
11 45.005166221 127.0.0.1 127.0.0.1 TCP 66 [TCP Keep-Alive ACK] 2807 → 45064 [ACK] Seq=1 Ack=589 Win=44928 Len=0 TSval=7245120 TSecr=7233868
正如你看到的,我的程序發送一個FIN標誌,這是不存在的netcat的。我在哪裏錯了?
請勿發佈圖片的文字! – Olaf
@Olaf我不會精確地調用Wireshark截圖文本的圖像。你不能只複製/粘貼數據包列表,至少不容易。 – dbush
@dbush:你可以將它轉儲到一個文本文件(不知道它是否可以轉儲到剪貼板)。 – Olaf