我有一个C#TCP服务器和一个C ++ TCP客户端(使用winsock2)。我正在尝试发送多封邮件,但仅收到第一封邮件...
C#服务器代码
IPAddress raw = IPAddress.Parse("127.0.0.1");
IPEndPoint ip = new IPEndPoint(raw, 7777);
Socket client = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
client.Bind(ip);
client.Listen(69);
Console.WriteLine("Waiting for connection.");
Socket conn = client.Accept();
Console.WriteLine("Got connection");
string message;
int bytesRecv;
byte[] recvBuf = new byte[100];
bytesRecv = conn.Receive(recvBuf);
Console.WriteLine("Received message, bytes: " + bytesRecv);
message = System.Text.Encoding.UTF8.GetString(recvBuf);
Console.WriteLine(message);
Array.Clear(recvBuf, 0, recvBuf.Length);
bytesRecv = conn.Receive(recvBuf);
Console.WriteLine("Received message, bytes: " + bytesRecv);
message = System.Text.Encoding.UTF8.GetString(recvBuf);
Console.WriteLine(message);
Array.Clear(recvBuf, 0, recvBuf.Length);
bytesRecv = conn.Receive(recvBuf);
Console.WriteLine("Received message, bytes: " + bytesRecv);
message = System.Text.Encoding.UTF8.GetString(recvBuf);
Console.WriteLine(message);
Array.Clear(recvBuf, 0, recvBuf.Length);
bytesRecv = conn.Receive(recvBuf);
Console.WriteLine("Received message, bytes: " + bytesRecv);
message = System.Text.Encoding.UTF8.GetString(recvBuf);
Console.WriteLine(message);
Array.Clear(recvBuf, 0, recvBuf.Length);
Console.ReadLine();
这是C ++代码
#pragma once
#include "pch.h"
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include <string>
#include<winsock2.h>
#include <WS2tcpip.h>
#pragma (lib, "ws2_32.lib")
using namespace std;
int main()
{
WSAData wsaData;
SOCKADDR_IN addr;
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
cout << "startup gave: " << result << endl;
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
addr.sin_family = AF_INET;
addr.sin_port = htons(7777);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
result = connect(s, (SOCKADDR*)&addr, sizeof(addr));
cout << "Connect gave: " << result << endl;
int count = 0;
char sendBuf[1024] = "Hello";
int sendResult;
sendResult = send(s, sendBuf, sizeof(sendBuf), 0);
sendResult = send(s, sendBuf, sizeof(sendBuf), 0);
sendResult = send(s, sendBuf, sizeof(sendBuf), 0);
sendResult = send(s, sendBuf, sizeof(sendBuf), 0);
}
为什么只收到第一条消息?服务器在一个recv语句中接收所有字节,因此(我知道)没有理由不应该这样做。谢谢!
在每个服务器的接收语句中接收到100字节(已发送的全部数据)。
答案 0 :(得分:2)
sizeof
返回对象的大小。在这种情况下,并非实际上所有对象都在使用,但是sizeof
不在乎。它总是返回对象的大小。使用
char sendBuf[1024] = "Hello";
不管使用多少个字符, sizeof(sendBuf)
始终为1024。这意味着
send(s, sendBuf, sizeof(sendBuf), 0);
发送"Hello\0"
以及其他1018个未指定的字节(由于char sendBuf[1024] = "Hello";
的初始化方式,所以肯定会全部为空字符),但是找不到。 sendbuf。重复此代码4次,总共发送了4096个字节。我的.Net不稳定,但是
byte[] recvBuf = new byte[100];
conn.Receive(recvBuf);
将最多接收100个字节。这是 Hello 和一大堆空字符。您必须阅读其中的10.24,以获取所有其他空值,以查找下一个 Hello 。
第一个
message = System.Text.Encoding.UTF8.GetString(recvBuf);
可以打印出 Hello ,但是接下来的三个只能看到100字节的空字符。
解决方案:
仅发送您需要发送的内容。
char sendBuf[1024] = "Hello";
sendResult = send(s, sendBuf, strlen(sendBuf), 0); // send all characters up to the
// first null character
或
char sendBuf[] = "Hello"; // buffer will be sized to fit string(including null)
sendResult = send(s, sendBuf, sizeof(sendBuf), 0);
注意事项:
TCP / IP是流协议。它没有单个消息的概念,并且可以根据需要将对send
的单个调用愉快地合并到一个或多个数据包中。这意味着第一次接收可能会返回所有四个 Hello 。
此外,在给定的TCP套接字读取的情况下,接收方永远不会真正知道要接收的内容。一条消息可能已被拆分为两个数据包以最大化吞吐量,并且其中一个数据包可能已路由很长的距离,并且在客户端读取该消息时不可用。
您将需要建立并使用通信协议来区分您的消息。发送字符串时,我更喜欢以integer of known size和字节序发送字符串的大小,然后发送该字符串。接收器读取字符串的长度(并确保在继续操作之前已获得所有长度),然后读取长度字节(同样,不多也不少)以获取字符串。