我正在為我正在從事的專案用 C 語言構建自己的 netcat 樣式偵聽器。客戶端(在本例中為 linux)使用 netcat 連接到偵聽器,并且我可以從偵聽器發送 linux 命令。當運行提供小輸出的命令(例如 whoami、uname、pwd)時,輸出恢復正常。但是,當運行一個可以提供大量輸出的命令時(例如 ls -la),我只能得到部分輸出,直到我發送另一個命令,這意味著后續命令正在執行前一個命令。截屏:

圖 1:輸出開始

圖 2:輸入另一個命令強制輸出完成

圖 3:現在我落后一個命令,輸出不正確。
代碼如下(包括/定義/其他功能,為簡潔起見):
int main(int argc, char *argv[])
{
char readbuff[262144];
char user_input[1024] = "";
struct sockaddr_in srv, cln;
int bnd, checkrtr, len, lstn, new_sfd, rd, result, sfd, val;
if(argc != 2)
{
fprintf(stderr, "[*]Usage: %s <target_router>\n", argv[0]);
return -1;
}
check_router(argv[1]);
// Start a listener on port 8888
// Create the socket
sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd == -1)
{
fprintf(stderr, "\n[*]socket: %s (%d)", strerror(errno), errno);
return -1;
}
else
{
fprintf(stdout, "\n[*]Socket created.");
}
val = 1;
result = 0;
result = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
if(result == -1)
{
fprintf(stderr, "\n[*]setsockopt: %s (%d)", strerror(errno), errno);
}
else
{
fprintf(stdout, "\n[*]Address reuse set");
}
srv.sin_family = AF_INET;
srv.sin_addr.s_addr = inet_addr(IP);
srv.sin_port = htons(atoi(LPORT));
len = sizeof(srv);
bnd = bind(sfd, (struct sockaddr*)&srv, len);
if(bnd != 0)
{
fprintf(stderr, "\n[*]bind: %s (%d)", strerror(errno), errno);
return -1;
}
else
{
fprintf(stdout, "\n[*]Socket bound");
}
lstn = listen(sfd, 10);
if(lstn != 0)
{
fprintf(stderr, "\n[*]listen: %s (%d)", strerror(errno), errno);
return -1;
}
else
{
fprintf(stdout, "\n[*]Server listening on %s:%s", IP, LPORT);
}
socklen_t len_c = sizeof(cln);
new_sfd = accept(sfd, (struct sockaddr*)&cln, &len_c);
if(new_sfd == -1)
{
fprintf(stderr, "\n[*]accept: %s (%d)", strerror(errno), errno);
return -1;
}
else
{
char *ip_c = inet_ntoa(cln.sin_addr);
fprintf(stdout, "\n[*]New connection from client: %s:%d\n", ip_c, ntohs(cln.sin_port));
while(1)
{
memset(readbuff, 0x00, sizeof(readbuff));
memset(user_input, 0x00, sizeof(user_input));
fgets(user_input, sizeof(user_input), stdin);
if(user_input[0] == '\n')
{
continue;
}
int send_data = send(new_sfd, user_input, sizeof(user_input), 0);
if(send_data == -1)
{
fprintf(stderr, "\n[*]send: %s (%d)", strerror(errno), errno);
continue;
}
rd = read(new_sfd, readbuff, sizeof(readbuff));
fprintf(stdout, "\n size of rd: %d", rd);
fprintf(stdout, "\n size of readbuff: %ld", sizeof(readbuff));
if(rd > 0)
{
fprintf(stdout, "\n%s", readbuff);
}
else if(rd == 0)
{
fprintf(stdout, "\n[*]Client connection closed.\n");
continue;
//break;
}
else
{
fprintf(stderr, "\n[*]recv: %s (%d)", strerror(errno), errno);
continue;
}
}
}
}
有人能給我一個為什么輸出中途停止的原因嗎?
uj5u.com熱心網友回復:
這是完全可以預料的。
單個read只能讀取到目前為止已收到的資料(否則它需要彎曲時間和空間)。另一端也可能在您發出時還沒有發送他們必須發送的所有內容read,因此單個人read也無法讀取所有內容(因為,它可能尚未發送)。
由于 TCP 是一種流協議,因此您需要設計一種方法來了解來自另一端的單個“訊息”需要多少位元組,并準確讀取那么多位元組,這樣您就知道您已經獲得了另一端的所有資訊說;我推薦某種型別-長度-值方案,即使您目前不需要超過 1 種型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/512333.html
標籤:C插座服务器网猫
上一篇:Socket.io-TypeError:無法設定未定義的屬性(設定“傳輸”)
下一篇:Python非阻塞套接字
