recv()char数组大小

时间:2017-02-18 02:39:21

标签: c++ sockets winsock

我正致力于实现C ++客户端服务器聊天程序,以了解更多/练习套接字编程。我使用的是winsockV2。

简言之, 客户端程序连接到服务器,该服务器将客户端套接字存储在向量中 客户端程序为服务器发送消息以分发给向量中的其他客户端。

我认为我遇到的问题是客户端和服务器正在接收消息并将其存储在char message[256]中,如果消息短于256,则在{I}时显示奇怪的字符我被告知的{1}}是未初始化的记忆。这是输出的一个例子:

std::cout << message;

是否有某种方法可以创建接收邮件大小的字符数组?即

k:message from client to other client╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠(■o

否则您对char recvMessage[4096]; int s = recv(socket, recvMessage, sizeof(recvMessage),0); char recvOutput[strlen(recvMessage)] = recvMessage; std::cout << recvOutput << std::endl; 消息的解决方案是什么,您不知道其长度?

如果我是一个完全白痴,请善待,我来自PHP。课程如下:

SVR.CPP

查看recvreceiveMessages()函数

distributeMessages()

CLI.CPP

查看#include "stdafx.h" #include "svr.h" svr::svr() { //WSA Business I don't understand WORD wVersionRequested; WSADATA wsaData; int err; /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { /* Tell the user that we could not find a usable */ /* Winsock DLL. */ printf("WSAStartup failed with error: %d\n", err); } //End of WSA Business //get addressSize addressSize = sizeof(address); //set address data members address.sin_family = AF_INET; address.sin_port = htons(444); address.sin_addr.s_addr = INADDR_ANY; //init sListen sListen = socket(AF_INET, SOCK_STREAM, 0); bind(sListen, (sockaddr*)&address, addressSize); } svr::~svr() { } void svr::start() { std::thread newConnThread(&svr::newConnection, this); newConnThread.join(); } void svr::receiveMessages(int clientIndex) { std::cout << "\tsvr::recv thread started for client index:" << clientIndex << std::endl; //create char arr char recvMessage[256]; //forever while (true) { //receive message and input it to recvMessage char arr. recv(clients[clientIndex], recvMessage, sizeof(recvMessage), 0); //if message is not null, send out to other clients if (recvMessage != NULL) { std::cout << "\t\tINFO:Received message of length: " << std::strlen(recvMessage) << " size: " << sizeof(recvMessage) << " : " << recvMessage << std::endl; distributeMessages(recvMessage, clientIndex); } } } //distributes messages to all clients in vector. called by receiveMessages function, normally in rMessages thread. void svr::distributeMessages(std::string message, int clientIndex) { for (unsigned int i = 0; i < clients.size(); i++) { if (clientIndex != i) { send(clients[i], message.c_str(), message.length(), 0); } else { //would have sent to self, not useful. } } } //accepts new connections and adds sockets to vector. void svr::newConnection() { //mark for accept, unsure of somaxconn value; listen(sListen, SOMAXCONN); std::cout << "\tSERVER: awaiting new connections..." << std::endl; while (true) { //accept connection and push on to vector. clients.push_back(accept(sListen, (sockaddr*)&address, &addressSize)); //responds to new clients. const char *message = "Hi, you've successfully connected!"; int clientIndex = clients.size() - 1; int sent = send(clients[clientIndex], message, 33, 0); //start new receiveMessage thread std::thread newClient(&svr::receiveMessages, this, clientIndex); //detach here, let newConn thread operate without depending on receiveMessages newClient.detach(); } std::cout << "\tSERVER: no longer listening for new connections" << std::endl; } cSend()函数

cRecv()

1 个答案:

答案 0 :(得分:4)

  

你的recv消息解决方案是什么,你不知道   长度?

recv()告诉您收到的邮件的长度。你不必怀疑它是什么。这是recv()的返回值。

 int s = recv(socket, recvMessage, sizeof(recvMessage),0);

看 - 你走了。它就在你面前。它是s。当然,如果有错误s将是否定的,您需要检查它。但是,忽略那些细节,你的担忧就结束了:s是你收到的信息的长度。

 char recvOutput[strlen(recvMessage)] = recvMessage;

那不行。 strlen()在这做什么? strlen()计算字符串的大小,期望字符串是一个老式的C风格字符串,以\0字节结束。 recv()不会终止使用\0字节收到的任何内容。相反,它返回实际的字符数。

此外,无论如何,这还不行。你无法通过这种方式初始化数组。

显然,你明显的意图是期望收到一个文本字符串作为消息。好吧,既然你选择的语言是C++,并且你标记了你的问题,那么合乎逻辑的结论就是你应该使用C++给你处理文本字符串的内容:{{1} } class:

std::string

你去吧。任务完成。由于您已经知道std::string recvOutput{recvMessage, recvMessage+s}; 中收到的邮件的长度,正如我们之前确定的那样(并且在仔细检查s不是否定之后),您只需使用{{1}现有的构造函数初始化新字符串给定一个迭代器或指针,指向字符串的开头和结尾。

在处理低级操作系统接口(如套接字)时,您别无选择,只能使用原始数据类型,例如普通s数组和缓冲区,因为这是操作的唯一内容系统理解。但是,使用C ++库提供的丰富的模板和类,您的代码应该在第一时间切换到使用C ++类和模板,以便能够使用所有这些资源。因此,只要您确定了文本字符串std::string刚刚提出的大小,只需将其填入char,然后再确定如何处理它。