通过动态分配 space 在套接字上接收 recv()
recv() on socket by dynamically allocating space
我正在尝试使用 c 获取我网站的源代码,我能够连接和一切,但是当我实现 recv() 代码时,它只接收源代码的最后几个字节。我想使用 C 函数 malloc
和 realloc
.
为缓冲区动态分配 space 以接收更多
这是我目前的代码:
char *buffer = NULL;
unsigned int i = 0;
unsigned long LEN = 200;
unsigned long cur_size = 0;
buffer = (char*)malloc(sizeof(char)*LEN);
do
{
if( status >= LEN )
{
cur_size += status;
buffer = (char*)realloc(buffer, cur_size);
}
status = recv(cSocket, buffer, LEN, 0);
if( status == 0 )
{
printf("Bye\n");
}
else if( status > 0 )
{
printf("%d\n", status);
}
else
{
printf("socket error=%d\n", WSAGetLastError());
break;
}
}while( status > 0 );
printf("%s\n", buffer);
它仍然没有打印出完整的源代码。我该怎么办?
伪代码:
buffer = 'len chars';
loop:
if( status >= buffer ) buffer = 'resize to status chars';
status = recv(sock, buffer, len, 0);
end loop
当您提前调整缓冲区大小时,这需要通过其大小反映出来。目前不是这种情况。
要解决此问题,例如,您可以通过更改
将 cur_size
初始化为 LEN
unsigned long cur_size = 0;
到
unsigned long cur_size = LEN;
假设上述修复,您希望附加到缓冲区而不是在每次调用 recv()
.
时覆盖它
为此更改此行
status = recv(cSocket, buffer, LEN, 0);
成为
status = recv(cSocket, buffer + cur_size - LEN, LEN, 0);
更直接的方法是不跟踪缓冲区的大小,而是跟踪接收到的字节数,并且始终将缓冲区增加一个恒定大小。
另外两次分配内存的调用可以用一次代替:
char *buffer = NULL;
unsigned long LEN = 200;
unsigned long bytes_received = 0;
unsigned long cur_size = 0;
int status = 0;
do
{
if (bytes_received >= cur_size)
{
char * tmp;
cur_size += LEN;
tmp = realloc(buffer, cur_size);
if (NULL == tmp)
{
fprintf(stderr, "realloc error=%d\n", WSAGetLastError());
break;
}
buffer = tmp;
}
status = recv(cSocket, buffer + bytes_received, LEN, 0);
if (status == 0)
{
printf("Bye\n");
}
else if (status > 0)
{
bytes_received += status;
printf("%d\n", status);
}
else /* < 0 */
{
fprintf(stderr, "socket error=%d\n", WSAGetLastError());
}
} while (status > 0);
printf("%s\n", buffer);
嗯,经过一番研究,我发现了这个网站,终于找到了我要找的东西。
虽然它使用了linux的fcntl
,但windows等同于ioctlsocket
,用于设置套接字的非阻塞模式。
要查看确切的功能,请访问该网站。我修改了版本并将我的套接字设置为阻塞模式。
int total_recv(SOCKET s)
{
int size_recv = 0, total_size = 0, block = 00;
char chunk[BUFLEN];
ioctlsocket(s, FIONBIO, (unsigned long*)&block); // set mode to block
// not necessary but clarification of function, mode is block by
// default
while( 1 )
{
memset(chunk, 0, BUFLEN);
if( ( size_recv = recv(s, chunk, BUFLEN, 0) ) == SOCKET_ERROR )
{
printf("Error receiving\n");
}
else if( size_recv == 0 )
{
break;
}
else
{
total_size += size_recv;
// i used file since console wouldn't show full source code
FILE *fp = NULL;
fp = fopen("source.txt", "a");
fprintf(fp, chunk);
fclose(fp);
}
}
return total_size;
}
我正在尝试使用 c 获取我网站的源代码,我能够连接和一切,但是当我实现 recv() 代码时,它只接收源代码的最后几个字节。我想使用 C 函数 malloc
和 realloc
.
这是我目前的代码:
char *buffer = NULL;
unsigned int i = 0;
unsigned long LEN = 200;
unsigned long cur_size = 0;
buffer = (char*)malloc(sizeof(char)*LEN);
do
{
if( status >= LEN )
{
cur_size += status;
buffer = (char*)realloc(buffer, cur_size);
}
status = recv(cSocket, buffer, LEN, 0);
if( status == 0 )
{
printf("Bye\n");
}
else if( status > 0 )
{
printf("%d\n", status);
}
else
{
printf("socket error=%d\n", WSAGetLastError());
break;
}
}while( status > 0 );
printf("%s\n", buffer);
它仍然没有打印出完整的源代码。我该怎么办?
伪代码:
buffer = 'len chars';
loop:
if( status >= buffer ) buffer = 'resize to status chars';
status = recv(sock, buffer, len, 0);
end loop
当您提前调整缓冲区大小时,这需要通过其大小反映出来。目前不是这种情况。
要解决此问题,例如,您可以通过更改
将cur_size
初始化为 LEN
unsigned long cur_size = 0;
到
unsigned long cur_size = LEN;
假设上述修复,您希望附加到缓冲区而不是在每次调用 recv()
.
为此更改此行
status = recv(cSocket, buffer, LEN, 0);
成为
status = recv(cSocket, buffer + cur_size - LEN, LEN, 0);
更直接的方法是不跟踪缓冲区的大小,而是跟踪接收到的字节数,并且始终将缓冲区增加一个恒定大小。
另外两次分配内存的调用可以用一次代替:
char *buffer = NULL;
unsigned long LEN = 200;
unsigned long bytes_received = 0;
unsigned long cur_size = 0;
int status = 0;
do
{
if (bytes_received >= cur_size)
{
char * tmp;
cur_size += LEN;
tmp = realloc(buffer, cur_size);
if (NULL == tmp)
{
fprintf(stderr, "realloc error=%d\n", WSAGetLastError());
break;
}
buffer = tmp;
}
status = recv(cSocket, buffer + bytes_received, LEN, 0);
if (status == 0)
{
printf("Bye\n");
}
else if (status > 0)
{
bytes_received += status;
printf("%d\n", status);
}
else /* < 0 */
{
fprintf(stderr, "socket error=%d\n", WSAGetLastError());
}
} while (status > 0);
printf("%s\n", buffer);
嗯,经过一番研究,我发现了这个网站,终于找到了我要找的东西。
虽然它使用了linux的fcntl
,但windows等同于ioctlsocket
,用于设置套接字的非阻塞模式。
要查看确切的功能,请访问该网站。我修改了版本并将我的套接字设置为阻塞模式。
int total_recv(SOCKET s)
{
int size_recv = 0, total_size = 0, block = 00;
char chunk[BUFLEN];
ioctlsocket(s, FIONBIO, (unsigned long*)&block); // set mode to block
// not necessary but clarification of function, mode is block by
// default
while( 1 )
{
memset(chunk, 0, BUFLEN);
if( ( size_recv = recv(s, chunk, BUFLEN, 0) ) == SOCKET_ERROR )
{
printf("Error receiving\n");
}
else if( size_recv == 0 )
{
break;
}
else
{
total_size += size_recv;
// i used file since console wouldn't show full source code
FILE *fp = NULL;
fp = fopen("source.txt", "a");
fprintf(fp, chunk);
fclose(fp);
}
}
return total_size;
}