一次发送一些字节

时间:2012-06-10 21:43:41

标签: c++ c

我正在试图找出从字符串ech时间发送一些文本的方法,直到它到达字符串的末尾,例如:

const char* the_string = "hello world, i'm happy to meet you all. Let be friends or maybe more, but nothing less

输出:hello world

输出:我很高兴认识你们。

输出:成为朋友或者更多

输出:,但不能少

停止:不再需要发送字节。

我搜索谷歌的问题,但是不明白这些例子,我花了4天时间尝试找到一个好方法,也就是发送5个字节的时间,但是如果有更少,那么发送它们直到你在字符串的结尾。

请帮助我们,我会接受一种C或C ++方式,只要它有效并且解释得很好。

3 个答案:

答案 0 :(得分:2)

根据评论中的讨论,我相信OP正在寻找的是他能够通过套接字发送整个数据的方式。

使用C ++和模板,通过套接字发送任意数据(出于本代码示例的目的,我将使用WinSock)非常简单。

常规发送功能:

template <typename T>
int                 SendData( const T& tDataBuffer, SOCKET sSock ) 
{
    // Make sure the class is trivially copyable:
    static_assert( std::is_pod<T>::value && !std::is_pointer<T>::value, "The object type must be trivially copyable" );

    char* chPtr = (char*)(&tDataBuffer);

    unsigned int iSent = 0;
    for( unsigned int iRemaining = sizeof(T); iRemaining > 0; iRemaining -= iSent )
    {
        iSent = send( sSock, chPtr, iRemaining, 0 );
        chPtr += iSent;

        if( iSent <= 0 )
        {
            return iSent;
        }
    }


    return 1;
}

指针重载:

template <typename T>
int                 SendData( T* const &ptObj, unsigned int iSize, SOCKET sSock )
{
    // Make sure the class is trivially copyable:
    static_assert( std::is_pod<T>::value, "The object type must be trivially copyable" );

    char* chPtr = (char*)ptObj;

    unsigned int iSent = 0;
    for( unsigned int iRemaining = iSize; iRemaining > 0; iRemaining -= iSent )
    {
        iSent = send( sSock, chPtr, iRemaining, 0 );
        chPtr += iSent;

        if( iSent <= 0 )
        {
            return iSent;
        }
    }

    return 1;
}

std::string的专业化:

template <>
int                 SendData( const std::string& szString, SOCKET sSock )
{
    // Send the size first:
    int iResult = SendData( static_cast<unsigned int>(szString.length()) * sizeof(char) + sizeof('\0'), sSock );

    if( iResult <= 0 )
        return iResult;

    iResult = SendData(szString.c_str(), static_cast<unsigned int>(szString.length()) * sizeof(char) + sizeof('\0'), sSock);
    return iResult;
}

利用这些功能的例子如下:

std::string szSample = "hello world, i'm happy to meet you all. Let be friends or maybe more, but nothing less";

// Note that this assumes that sSock has already been initialized and your connection has been established:
SendData( szSample, sSock );

希望这有助于您实现自己想要的目标。

答案 1 :(得分:1)

在c ++中,您可以使用substring(substr)方法选择要发送的字符串的一部分。在c中,您必须手动遍历字符,在达到零时停止或者发送所需的字节数,或者将char数组的一部分复制到另一个0终止的数组并发送。

例如,您可以一次发送10个字符,如下所示:

string str = randomstaff.from(whereveryoulike);
for (int i = 0; i < str.size(); i += 10)
{
    destination << str.substr(i, i + 10 < str.size() ? i + 10 : str.size());
}

答案 2 :(得分:1)

这是C中的解决方案。希望我理解你的问题。

void send_substr(
    const char * str,
    size_t len,
    const size_t bytes_at_a_time,
    void (*sender)(const char *)
    )
/*
   sender() must check the char * manually for
   null termination or call strlen()

   for Unicode just change all size_t to unsigned long
   and all const char * to const wchar_t * (POSIX)
   or LPCWSTR (Win32)
 */
{
  size_t i, index_to_end, tail;

  //for C99 (gcc)
  char ret[bytes_at_a_time];

  //for C89 (Visual C++)
  //char * ret = (char *) malloc(sizeof(char)*bytes_at_a_time);

  tail = len % bytes_at_a_time;
  index_to_end = len - tail;

  for(i = 0; i < index_to_end; i += bytes_at_a_time)
  {
    memcpy(ret, str+i, bytes_at_a_time);
    *(ret + bytes_at_a_time) = '\0';
    (*sender)(ret);
  }
  memcpy(ret, str+index_to_end, tail);
  *(ret + tail) = '\0';
  (*sender)(ret);
  //for C89
  //free(ret);
}

void print_substr(const char * substr)
{
  while(*substr != '\0')
  {
    putchar(*substr);
    substr++;
  }
  putchar('\n');
}

int main()
{
  char test[] = "hello world, i'm happy to meet you all."
    " Let be friends or maybe more, but nothing less";
  send_substr(test, sizeof(test)/sizeof(*test), 5, &print_substr);

  return 0;
}