2016-04-12 34 views
0

发送数据时,我在winsock客户端服务器中遇到问题。我有一个包含一个用户名作为主键的映射,和消息的每个用户的矢量(存储在结构): map<std::string,std::vector<message *> > data;未在客户端Winsock中接收完整数据

struct message{ 
     static unsigned int last_id; 
     unsigned int id; 
     std::string baa; 
     std::string timestamp; 
    } 

我也有一个串行器,以便通过的Winsock将其发送到客户端(只接受字符数组)

class MessageSerializer 
{ 
public: 
    MessageSerializer(const message& messageStruct) 
    : m_msgRef(messageStruct) 
    , m_msgLength(m_msgRef.msg.length()) 
    , m_timeLength(m_msgRef.timestamp.length()) 
    {} 

    size_t RequiredBufferSize() const 
    { 
     return sizeof(int) + sizeof(size_t)*2 + m_msgLength + m_timeLength; 
    } 

    void Serialize(void* buffer) const 
    { 
     PushNum  (buffer, m_msgRef.id); 
     PushString (buffer, m_msgRef.msg.c_str(), m_msgLength); 
     PushString (buffer, m_msgRef.timestamp.c_str(), m_timeLength); 
    } 
private: 
    const message& m_msgRef; 
    const size_t m_msgLength; 
    const size_t m_timeLength; 

    template<typename INTEGER> 
    void PushNum(void*& buffer, INTEGER num) const 
    { 
     INTEGER* ptr = static_cast<INTEGER*>(buffer); 
     //copying content 
     *ptr = num; 
     //updating the buffer pointer to point the next position to copy 
     buffer = ++ptr; 
    } 
    void PushString(void*& buffer, const char* cstr, size_t length) const 
    { 
     PushNum(buffer, length); 
     //copying string content 
     memcpy(buffer, cstr, length); 
     //updating the buffer pointer to point the next position to copy 
     char* ptr = static_cast<char*>(buffer); 
     ptr += length; 
     buffer = ptr; 
    } 
} 

而要实现这个串,我做了以下内容:

message msg_cpy=*data[recvbuf_usrn].at(0); 
MessageSerializer serializer(msg_cpy); 
char* buffer = new char[serializer.RequiredBufferSize()]; 
serializer.Serialize(buffer); 

问题是当发送时间戳。在msg_cpy我有正确存储的数据(例如id = 1,msg = hello,timestamp = 2016-04-02 10:40:45),但是在发送数据时,时间戳只保存前三个值,即比如说,在客户端,我反序列化id = 1,msg = hello和timestamp = 201后面接收垃圾回收。我知道问题存在于服务器中,我推断它可以是序列化函数(唯一的其他选择可能是Winsock的“发送”函数)。但是有什么可能是错误的呢?如果我写了一个msg = 2016-04-02 10:40:20,我在客户端收到。

任何帮助表示赞赏

+0

你应该尝试建立一个[MCVE。问题可能在于你使用串行器发送数据的方式,也就是代码没有显示(并且我的水晶球当前没有使用...) –

+0

要发送数据,我发送从'serializer返回的'buffer' .Serialize(buffer)',因为Winsock函数只发送字符数组。 [链接](https://msdn.microsoft.com/es-es/library/windows/desktop/ms737593(v = vs.85).aspx)在此网页上显示Winsock的发送函数,它需要'recvbuf'作为输入数据,在我的情况下,它是缓冲区。但我认为问题存在于序列化时,其中缓冲区已经在时间戳部分中存在垃圾。这就是为什么我没有附加其余的。如果你有任何想法为什么会发生,我会很感激。不管怎么说,还是要谢谢你! @ serge-ballesta – Zarauztarra

+0

这只是一个狂野的预感,因为你没有包含发送/接收代码:TCP是一个面向流的协议;一个'recv()'可能不会返回所有的数据。您需要循环调用'recv()'直到收到完整的“消息”。 – keithmo

回答

1

您显示的代码是正确的。错误是你没有显示的代码。

随着2类messageMessageSerializer,我试过了简单的测试:

int main() { 
    message msg = {1, "foo", "2016-04-02 10:40:20" }; 

    MessageSerializer msgSer(msg); 

    size_t sz = msgSer.RequiredBufferSize(); 
    char * buffer = new char[sz]; 
    msgSer.Serialize(static_cast<void *>(buffer)); 
    for (int i=0; i<sz; i++) { 
     std::cout << buffer[i] << " (" << std::hex << static_cast<unsigned int>(buffer[i]) << ") "; 
    } 
    std::cout << std::endl; 
    delete[] buffer; 
    return 0; 
} 

结果如预期

(1) (0) (0) (0) (3) (0) (0) (0) f (66) o (6f) o (6f) (13) (0) (0) (0) 2 (32) 0 (30) 1 (31) 6 (36) - (2d) 0 (30) 4 (34) - (2d) 0 (30) 2 (32) (20) 1 (31) 0 (30) : (3a) 4 (34) 0 (30) : (3a) 2 (32) 0 (30) 
+0

你说得对。问题在于我在winsock发送函数中设置的缓冲区长度。序列化程序运行良好。 – Zarauztarra

相关问题