新手写的代码,你们看看问题在哪里?

时间:2021-07-06 20:25:15
#include <winsock2.h>
#include <stdio.h>
#include <string.h>


int ReadPage(char *str)
{
char packet[256],revData[1024]={0};;   
sprintf(packet,"GET /btc/search/%s/ HTTP/1.1\r\n"
"Host: block.okcoin.cn\r\n"
"Connection: keep-alive\r\n"
"Accept: text\r\n"
"User-Agent: Mozilla/5.0\r\n\r\n",str);
WSADATA wsaData;
    WORD sockVersion = MAKEWORD(2, 2);
if(WSAStartup(sockVersion, &wsaData) != 0) return 0;
    SOCKET sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sClient == INVALID_SOCKET)
{
printf("socket error\n");
return 0;
}
sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(80);
servAddr.sin_addr.S_un.S_addr =inet_addr("121.199.251.136");
if(connect(sClient,(sockaddr*)&servAddr,sizeof(servAddr))==SOCKET_ERROR)
{
printf("connect error\n");
closesocket(sClient);
return 0;
}
send(sClient,packet,strlen(packet),0);
while(recv(sClient,revData,BUFSIZ,0)>0){
printf("%s",revData);
}

closesocket(sClient);
WSACleanup();
return 0;
}



int main()
{
char szTest[1000] = {0};
char szTest2[1000] = {0};
FILE *fp = fopen("1.txt", "r");
if(NULL == fp)
{
printf("failed to open dos.txt\n");
return 1;
}
while(!feof(fp))
{
fgets(szTest, sizeof(szTest) - 1, fp); 
if(strstr(szTest,"Address:"))
{
sscanf(szTest, "%*s%s", szTest2);
printf("%s\n", szTest2);
ReadPage(szTest2);
}
}

fclose(fp);
getchar();
return 0;
}


问题一: recv收的内容打印出来 会在最后多出来一些代码  该怎能么解决啊
问题二: recv接收完毕后 为什么还要等待几十秒才会循环 执行下一次提交啊? 怎么样能接收完毕后 立即循环执行下一步?
问题三:代码里还有其他错误吗? 指正下 我以后纠正

14 个解决方案

#1


新手写的代码,你们看看问题在哪里?新手写的代码,你们看看问题在哪里?

#2


上图为我使用其他软件提交的  正常返回的  我写的代码返回为图2
我感觉 是接收数据的问题   不知道哪里写错了?

#3


	
while (recv(sClient, revData, BUFSIZ, 0)>0) {

printf("%s", revData);
                memset(revData,0,BUFSIZ);
}


问题2是啥意思?没懂

#4


	do
{
int len = recv(sClient, revData, BUFSIZ, 0);
printf("%s", revData);
memset(revData, 0, BUFSIZ);
if (!len || BUFSIZ != len)
break;
} while (true);

#5


引用 3 楼 qq_29846883 的回复:
	
while (recv(sClient, revData, BUFSIZ, 0)>0) {

printf("%s", revData);
                memset(revData,0,BUFSIZ);
}


问题2是啥意思?没懂


用menset是能解决 多接收的问题了, 但这样放循环体里面 重复执行menset t太浪费了 有没有其他方法

问题2就是  接收完 网站返回的数据后,recvbing并没有断开  还在等待接收状态  要等十几秒才会断开
那如何实现 接收完后 就立即循环 执行下一次的 向网站发送数据呢?

#6


查了很多   好像是因为 HTTP1.1  默认是在一个连接上允许多个HTTP的请求和响应 会持久连接 
我修改成Connection: close 或者使用HTTP1.0后  接收完数据 就断开连接了

    while(!feof(fp))
    {
        fgets(szTest, sizeof(szTest) - 1, fp); 
        if(strstr(szTest,"Address:"))
        {
            sscanf(szTest, "%*s%s", szTest2);
            printf("%s\n", szTest2);
            ReadPage(szTest2);
        }           
    }

这样就可以 发送数据后 接收完  就会断开 然后 循环 新一轮的ReadPage了

但是遇到一个问题 就是 这样的话每次发送一个数据都是 重新建立的新的tcp连接   
执行效率不高外  我的程序有时候 会经常没发送出去数据就退出程序了  是不是 频繁的初始化socket 连接 发送 会出现问题

如何能在 Connection: keep-alive 模式下  实现一个http连接内  发送数据和接收数据 

#7


WebSocket ?

#8


新手写的代码,你们看看问题在哪里?
#include <winsock2.h>
#include <stdio.h>

int main()
{
char address[]= "1BTCoinWDVhwD5Nov86QTMYvdjZ69Ho6mi";
char packet[256],revData[BUFSIZ]={0};;   
sprintf(packet, "GET /btc/search/%s/ HTTP/1.1\r\n"
"Host: block.okcoin.cn\r\n"
"Connection: close\r\n"
"User-Agent: Mozilla/5.0\r\n\r\n",address);
WSADATA wsaData;
    WORD sockVersion = MAKEWORD(2, 2);
if(WSAStartup(sockVersion, &wsaData) != 0) {puts("初始化错误");return 0;}
    SOCKET sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sClient == INVALID_SOCKET)
{
printf("socket error\n");
return 0;
}
sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(80);
servAddr.sin_addr.S_un.S_addr =inet_addr("121.199.251.136");
if(connect(sClient,(sockaddr*)&servAddr,sizeof(servAddr))==SOCKET_ERROR)
{
printf("connect error\n");
closesocket(sClient);
return 0;
}

char revTemp[100000]={0};
send(sClient,packet,strlen(packet),0);
while(recv(sClient,revData,BUFSIZ,0)>0){
strcat(revTemp,revData);
//printf("%s",revData);
memset(revData,0,BUFSIZ);
}
puts(revTemp);

搜索revTemp里面的节点
<span data-c="26849643">
0.26849643 BTC
</span>

并且打印出来,如果不用libcurl,怎么样该怎么写  想不出来了

closesocket(sClient);
WSACleanup();
return 0;
}

#9


引用 7 楼 zhao4zhong1 的回复:
WebSocket ?


是啊  就会一点c语言 和一点socket   ,像查询个网页数据  就用socket提交 http了
但是遇到很多问题    基本功太差了

#10


你似乎应该使用curl

#11


1、是因为接收缓冲中的以前接收的数据存在,新收到的数所没有以0结尾引起的。
    while(recv(sClient,revData,BUFSIZ,0)>0){
        printf("%s",revData);
    }

改为
   int length = 0;
    while((length = recv(sClient,revData,BUFSIZ-1,0))>0){
        recvData[length] = 0;
        printf("%s",revData);
    }

2、打印系统时间判断一下时间浪费在了哪里。可能是浪费在连接的时候,可以一次建立连接,多次使用。

#12


引用 11 楼 11287011 的回复:
1、是因为接收缓冲中的以前接收的数据存在,新收到的数所没有以0结尾引起的。
    while(recv(sClient,revData,BUFSIZ,0)>0){
        printf("%s",revData);
    }

改为
   int length = 0;
    while((length = recv(sClient,revData,BUFSIZ-1,0))>0){
        recvData[length] = 0;
        printf("%s",revData);
    }

2、打印系统时间判断一下时间浪费在了哪里。可能是浪费在连接的时候,可以一次建立连接,多次使用。


recvData[length] = 0;  这个方法不错   感觉比menset会执行快一些吧可以一次建立连接,多次使用  不会写代码  不知道怎么循环发送啊   因为http1.1本身协议就是支持长连接的  可以在在接收完数据后,继续发送, 

你知道为什么  recv接受的数据  不是一次性接收完吗?我发现每一次似乎接受了512 即使 recvData空间设置1024,它还是只接受了512,而不是最大化利用,  循环才可以读取完  这点也不太明白呢

#13


引用 10 楼 zhao4zhong1 的回复:
你似乎应该使用curl

 说得对,应该用curl会方便很多,  以后学习学习
上面的问题基本解决了 

8楼的问题 该怎么实现啊  就是提取接收到的数据(html源码)中的一个节点内的 数据
这个我在网上查了很多  都说要用xml或者html解析库  
C语言字符处理真麻烦

#14


memchr
Finds characters in a buffer.

void *memchr( const void *buf, int c, size_t count );

Routine Required Header Compatibility 
memchr <memory.h> or <string.h> ANSI, Win 95, Win NT 


For additional compatibility information, see Compatibility in the Introduction.

Libraries

LIBC.LIB Single thread static library, retail version 
LIBCMT.LIB Multithread static library, retail version 
MSVCRT.LIB Import library for MSVCRT.DLL, retail version 


Return Value

If successful, memchr returns a pointer to the first location of c in buf. Otherwise it returns NULL.

Parameters

buf

Pointer to buffer

c

Character to look for

count

Number of characters to check

Remarks

The memchr function looks for the first occurrence of c in the first count bytes of buf. It stops when it finds c or when it has checked the first count bytes.

Example

/* MEMCHR.C */

#include <memory.h>
#include <stdio.h>

int  ch = 'r';
char str[] =    "lazy";
char string[] = "The quick brown dog jumps over the lazy fox";
char fmt1[] =   "         1         2         3         4         5";
char fmt2[] =   "12345678901234567890123456789012345678901234567890";

void main( void )
{
   char *pdest;
   int result;
   printf( "String to be searched:\n\t\t%s\n", string );
   printf( "\t\t%s\n\t\t%s\n\n", fmt1, fmt2 );

   printf( "Search char:\t%c\n", ch );
   pdest = memchr( string, ch, sizeof( string ) );
   result = pdest - string + 1;
   if( pdest != NULL )
      printf( "Result:\t\t%c found at position %d\n\n", ch, result );
   else
      printf( "Result:\t\t%c not found\n" );
}


Output

String to be searched:
      The quick brown dog jumps over the lazy fox
               1         2         3         4         5
      12345678901234567890123456789012345678901234567890

Search char:   r
Result:      r found at position 12


Buffer Manipulation Routines

See Also   _memccpy, memcmp, memcpy, memset, strchr

#1


新手写的代码,你们看看问题在哪里?新手写的代码,你们看看问题在哪里?

#2


上图为我使用其他软件提交的  正常返回的  我写的代码返回为图2
我感觉 是接收数据的问题   不知道哪里写错了?

#3


	
while (recv(sClient, revData, BUFSIZ, 0)>0) {

printf("%s", revData);
                memset(revData,0,BUFSIZ);
}


问题2是啥意思?没懂

#4


	do
{
int len = recv(sClient, revData, BUFSIZ, 0);
printf("%s", revData);
memset(revData, 0, BUFSIZ);
if (!len || BUFSIZ != len)
break;
} while (true);

#5


引用 3 楼 qq_29846883 的回复:
	
while (recv(sClient, revData, BUFSIZ, 0)>0) {

printf("%s", revData);
                memset(revData,0,BUFSIZ);
}


问题2是啥意思?没懂


用menset是能解决 多接收的问题了, 但这样放循环体里面 重复执行menset t太浪费了 有没有其他方法

问题2就是  接收完 网站返回的数据后,recvbing并没有断开  还在等待接收状态  要等十几秒才会断开
那如何实现 接收完后 就立即循环 执行下一次的 向网站发送数据呢?

#6


查了很多   好像是因为 HTTP1.1  默认是在一个连接上允许多个HTTP的请求和响应 会持久连接 
我修改成Connection: close 或者使用HTTP1.0后  接收完数据 就断开连接了

    while(!feof(fp))
    {
        fgets(szTest, sizeof(szTest) - 1, fp); 
        if(strstr(szTest,"Address:"))
        {
            sscanf(szTest, "%*s%s", szTest2);
            printf("%s\n", szTest2);
            ReadPage(szTest2);
        }           
    }

这样就可以 发送数据后 接收完  就会断开 然后 循环 新一轮的ReadPage了

但是遇到一个问题 就是 这样的话每次发送一个数据都是 重新建立的新的tcp连接   
执行效率不高外  我的程序有时候 会经常没发送出去数据就退出程序了  是不是 频繁的初始化socket 连接 发送 会出现问题

如何能在 Connection: keep-alive 模式下  实现一个http连接内  发送数据和接收数据 

#7


WebSocket ?

#8


新手写的代码,你们看看问题在哪里?
#include <winsock2.h>
#include <stdio.h>

int main()
{
char address[]= "1BTCoinWDVhwD5Nov86QTMYvdjZ69Ho6mi";
char packet[256],revData[BUFSIZ]={0};;   
sprintf(packet, "GET /btc/search/%s/ HTTP/1.1\r\n"
"Host: block.okcoin.cn\r\n"
"Connection: close\r\n"
"User-Agent: Mozilla/5.0\r\n\r\n",address);
WSADATA wsaData;
    WORD sockVersion = MAKEWORD(2, 2);
if(WSAStartup(sockVersion, &wsaData) != 0) {puts("初始化错误");return 0;}
    SOCKET sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sClient == INVALID_SOCKET)
{
printf("socket error\n");
return 0;
}
sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(80);
servAddr.sin_addr.S_un.S_addr =inet_addr("121.199.251.136");
if(connect(sClient,(sockaddr*)&servAddr,sizeof(servAddr))==SOCKET_ERROR)
{
printf("connect error\n");
closesocket(sClient);
return 0;
}

char revTemp[100000]={0};
send(sClient,packet,strlen(packet),0);
while(recv(sClient,revData,BUFSIZ,0)>0){
strcat(revTemp,revData);
//printf("%s",revData);
memset(revData,0,BUFSIZ);
}
puts(revTemp);

搜索revTemp里面的节点
<span data-c="26849643">
0.26849643 BTC
</span>

并且打印出来,如果不用libcurl,怎么样该怎么写  想不出来了

closesocket(sClient);
WSACleanup();
return 0;
}

#9


引用 7 楼 zhao4zhong1 的回复:
WebSocket ?


是啊  就会一点c语言 和一点socket   ,像查询个网页数据  就用socket提交 http了
但是遇到很多问题    基本功太差了

#10


你似乎应该使用curl

#11


1、是因为接收缓冲中的以前接收的数据存在,新收到的数所没有以0结尾引起的。
    while(recv(sClient,revData,BUFSIZ,0)>0){
        printf("%s",revData);
    }

改为
   int length = 0;
    while((length = recv(sClient,revData,BUFSIZ-1,0))>0){
        recvData[length] = 0;
        printf("%s",revData);
    }

2、打印系统时间判断一下时间浪费在了哪里。可能是浪费在连接的时候,可以一次建立连接,多次使用。

#12


引用 11 楼 11287011 的回复:
1、是因为接收缓冲中的以前接收的数据存在,新收到的数所没有以0结尾引起的。
    while(recv(sClient,revData,BUFSIZ,0)>0){
        printf("%s",revData);
    }

改为
   int length = 0;
    while((length = recv(sClient,revData,BUFSIZ-1,0))>0){
        recvData[length] = 0;
        printf("%s",revData);
    }

2、打印系统时间判断一下时间浪费在了哪里。可能是浪费在连接的时候,可以一次建立连接,多次使用。


recvData[length] = 0;  这个方法不错   感觉比menset会执行快一些吧可以一次建立连接,多次使用  不会写代码  不知道怎么循环发送啊   因为http1.1本身协议就是支持长连接的  可以在在接收完数据后,继续发送, 

你知道为什么  recv接受的数据  不是一次性接收完吗?我发现每一次似乎接受了512 即使 recvData空间设置1024,它还是只接受了512,而不是最大化利用,  循环才可以读取完  这点也不太明白呢

#13


引用 10 楼 zhao4zhong1 的回复:
你似乎应该使用curl

 说得对,应该用curl会方便很多,  以后学习学习
上面的问题基本解决了 

8楼的问题 该怎么实现啊  就是提取接收到的数据(html源码)中的一个节点内的 数据
这个我在网上查了很多  都说要用xml或者html解析库  
C语言字符处理真麻烦

#14


memchr
Finds characters in a buffer.

void *memchr( const void *buf, int c, size_t count );

Routine Required Header Compatibility 
memchr <memory.h> or <string.h> ANSI, Win 95, Win NT 


For additional compatibility information, see Compatibility in the Introduction.

Libraries

LIBC.LIB Single thread static library, retail version 
LIBCMT.LIB Multithread static library, retail version 
MSVCRT.LIB Import library for MSVCRT.DLL, retail version 


Return Value

If successful, memchr returns a pointer to the first location of c in buf. Otherwise it returns NULL.

Parameters

buf

Pointer to buffer

c

Character to look for

count

Number of characters to check

Remarks

The memchr function looks for the first occurrence of c in the first count bytes of buf. It stops when it finds c or when it has checked the first count bytes.

Example

/* MEMCHR.C */

#include <memory.h>
#include <stdio.h>

int  ch = 'r';
char str[] =    "lazy";
char string[] = "The quick brown dog jumps over the lazy fox";
char fmt1[] =   "         1         2         3         4         5";
char fmt2[] =   "12345678901234567890123456789012345678901234567890";

void main( void )
{
   char *pdest;
   int result;
   printf( "String to be searched:\n\t\t%s\n", string );
   printf( "\t\t%s\n\t\t%s\n\n", fmt1, fmt2 );

   printf( "Search char:\t%c\n", ch );
   pdest = memchr( string, ch, sizeof( string ) );
   result = pdest - string + 1;
   if( pdest != NULL )
      printf( "Result:\t\t%c found at position %d\n\n", ch, result );
   else
      printf( "Result:\t\t%c not found\n" );
}


Output

String to be searched:
      The quick brown dog jumps over the lazy fox
               1         2         3         4         5
      12345678901234567890123456789012345678901234567890

Search char:   r
Result:      r found at position 12


Buffer Manipulation Routines

See Also   _memccpy, memcmp, memcpy, memset, strchr