我想将一个字符串发送到我的nodejs TCP服务器。
这是我的客户端代码(C ++):
#include <nds.h>
#include <dswifi9.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string>
std::string hostname = "hostname";
int port = 61733;
int sock;
int main(){
Connect(); //function to connect with a WiFi network
ConnectToServer();
unsigned long lastSendTime = 0;
unsigned long sendInterval = 200; //send a message every 200 milliseconds
unsigned int nMsgSent = 0;
while (1){
unsigned long now = milliseconds(); //function to get the time in milliseconds
if ((now - lastSendTime) > sendInterval){
std::string request = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
request += request;
request += std::to_string(nMsgSent);
request += "\n";
int sendResult = ::send(sock, request.c_str(), request.length(), 0);
iprintf("req(%d): %d\n", nMsgSent, sendResult);
nMsgSent++;
lastSendTime = now;
}
}
return 0;
}
这是我的服务器代码(JS):
var net = require('net');
var tcpServer = net.createServer();
var tcpPort = 61733;
tcpServer.on('connection', onConnection);
function onConnection(conn){
var remoteAddress = conn.remoteAddress + ':' + conn.remotePort;
console.log('New client connection from: %s', remoteAddress);
conn.on('data', onData);
conn.once('close', onClose);
conn.on('error', onError);
function onData(data){
console.log('connection data from %s: %s', remoteAddress, data);
}
function onClose(){
console.log('connection from %s closed', remoteAddress);
}
function onError(err){
console.log('Connection %s error: %s', remoteAddress, err.message);
}
}
tcpServer.listen(tcpPort, function(){
console.log('Server listening on: %j', tcpServer.address());
});
问题出现了:
客户端仅发送大约180条消息,然后send
挂起。服务器只接收~120条消息。当我增加请求的长度时,客户端发送的请求减少,当我减少长度时,客户端发送更多请求。我还发现当我减少sendInterval时,我可以在send
挂起之前发送更多请求。我不知道自己做错了什么。当我使用nodejs客户端执行类似的代码时,一切都很好,所以问题在于C ++客户端。
编辑:
我并不认为这是必要的,但这里是connectToServer()
的代码:
void ConnectToServer()
{
sock = socket(AF_INET, SOCK_STREAM, 0);
if (socket >= 0)
{
printf("Created Socket!\n");
}
else
{
printf("Couldn't create socket");
}
struct hostent * host = gethostbyname(hostname.c_str());
if (host != NULL)
{
printf("Found IP Address!\n");
}
else
{
printf("IP not found");
}
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = *((unsigned long *)(host->h_addr_list[0]));
int connectResult = ::connect(sock, (struct sockaddr *)&server, sizeof(server));
if (connectResult >= 0)
{
printf("Connected to server!\n");
}
else
{
printf("Not connected to server. Err: %d\n", connectResult);
}
}
C ++客户端的输出(发送间隔:2000ms,msgLength:126-127个字符):
req(1): 126
req(2: 126
req(3): 126
...keeps going on for a while...
req(9): 126
req(10): 126
req(11): 127
req(12): 127
...keeps going on for a while...
req(74): 64
send() hangs after this
来自nodejs服务器的输出(仅接收9条消息):
connection data from ip::port: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678900
...keeps going on for a while...
connection data from ip::port: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678909
测试结果以查看发送间隔,消息长度和已发送消息数之间是否存在连接:
sendInterval | msgLength | nMsg --------------------------------------- 200 | 127 | 26 200 | 65 | 33 --------------------------------------- 400 | 65 | 59 400 | 127 | 53 --------------------------------------- 2000 | 65 | 47 2000 | 127 | 21
(我没有看到这些值之间的联系)
答案 0 :(得分:0)
我可以看到你应该参加一些问题:
sendResult
。在发送另一个之前应该检查它
消息。sleep
或std::chrono
的间隔,并调用一个按套接字发送消息但不在同一个线程中的方法< em> TSync 因为你将使用sleeps来阻止套接字。FD_SET
和select
来检查何时可以通过套接字发送数据。 可能是您无控制地发送消息的方式会影响TX通道,因为它正在变得充满所以您应该使用FD_SET
和{{1}来控制输出操作与套接字同步。在写的情况下,Microsoft documentation说:
select函数用于确定一个或多个套接字的状态。对于每个套接字,调用者可以请求有关读,写或错误状态的信息。
writefds :可以发送数据。
更新,4月21日:我建议您分享有关您的问题的更多信息,例如服务器的代码和配置,以了解是否配置了超时或缓冲区大小。您提供的信息是不够的,并没有低估我们向您发出的请求,如此评论:
我真的不认为这是必要的,但这里是connectToServer()的代码:
连接过程很重要,因为我们可以看到套接字服务器是否设置了一些选项。
在这种情况下,您与我们分享的所有信息都可能有所帮助,而不是假设这不重要。
所以,在这一刻,这就是我可以帮助你的一切。
4月24日更新:尝试以下步骤来控制套接字传输并设置 NON-Blocing 套接字:
连接成功后,在客户端中将套接字设置为NON-BLOCKING。
在循环文件描述符(select
)和FD_SET
中使用,以检查套接字何时可以写入。
您的代码应该包含以下代码:
select