我有一个C ++客户端程序(用VS2005编写),我想将消息发送到C#服务器程序(用VS2017编写)。虽然建立了连接,但消息似乎没有传递到服务器,我正在努力弄清楚原因。任何人都可以帮我确定哪里出错了?
TestServer.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Collections;
using System.Net;
class TcpServer
{
private TcpListener _server;
private Boolean _isRunning;
public TcpServer(int port)
{
_server = new TcpListener(IPAddress.Any, port);
_server.Start();
_isRunning = true;
LoopClients();
}
public void LoopClients()
{
while (_isRunning)
{
// wait for client connection
TcpClient newClient = _server.AcceptTcpClient();
// client found.
// create a thread to handle communication
Thread t = new Thread(new ParameterizedThreadStart(HandleClient));
t.Start(newClient);
}
}
public void HandleClient(object obj)
{
// retrieve client from parameter passed to thread
TcpClient client = (TcpClient)obj;
//
int i = 0;
string data = null;
Byte[] bytes = new Byte[256];
Stream s = client.GetStream();
StreamReader Reader = new StreamReader(s);
StreamWriter Writer = new StreamWriter(s);
Writer.NewLine = "\r\n";
Writer.AutoFlush = true;
byte[] serverData = new byte[client.ReceiveBufferSize];
int length = s.Read(serverData, 0, serverData.Length);
string received = Encoding.ASCII.GetString(serverData, 0, length);
while ((i = s.Read(bytes, 0, bytes.Length)) != 0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: {0}", data);
// Process the data sent by the client.
data = data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
// Send back a response.
s.Write(msg, 0, msg.Length);
Console.WriteLine("Sent: {0}", data);
}
}
}
namespace Multi_Threaded_TCP
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Multi-Threaded TCP Server Demo");
TcpServer server = new TcpServer(1111);
}
}
}
TestClient.cpp
#pragma comment(lib,"ws2_32.lib")
#include <WinSock2.h>
#include <iostream>
int main()
{
//Winsock Startup
WSAData wsaData;
WORD DllVersion = MAKEWORD(2, 1);
if (WSAStartup(DllVersion, &wsaData) != 0) //If WSAStartup returns anything other than 0, then that means an error has occured in the WinSock Startup.
{
MessageBoxA(NULL, "Winsock startup failed", "Error", MB_OK | MB_ICONERROR);
exit(1);
}
SOCKADDR_IN addr; //Address to be binded to our Connection socket
int sizeofaddr = sizeof(addr); //Need sizeofaddr for the connect function
addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //Address = localhost (this pc)
addr.sin_port = htons(1111); //Port = 1111
addr.sin_family = AF_INET; //IPv4 Socket
SOCKET Connection = socket(AF_INET, SOCK_STREAM, NULL); //Set Connection socket
if (connect(Connection, (SOCKADDR*)&addr, sizeofaddr) != 0) //If we are unable to connect...
{
MessageBoxA(NULL, "Failed to Connect", "Error", MB_OK | MB_ICONERROR);
return 0; //Failed to Connect
}
else
{
std::cout << "Connected!" << std::endl;
}
char MOTD[256] = "Hello there Server, Please run task a & b":) //Create buffer with message
send(Connection, MOTD, sizeof(MOTD), NULL);
while (true)
{
Sleep(10); // keep program running
}
}
答案 0 :(得分:1)
在客户端,您没有检查send()
的返回值以确保实际发送了所有256个字节。它可能会返回更少的字节。在这种情况下,您必须在循环中调用send()
,直到所有字节都已发送。
在服务器端,它尝试执行8192字节(默认值ReceiveBufferSize
)的初始读取,而不是256字节。但是,它期望客户端发送多个字符串,但客户端只发送1个字符串。
尝试更像这样的东西:
TestServer.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Collections;
using System.Net;
class TcpServer
{
private TcpListener _server;
private Boolean _isRunning;
public TcpServer(int port)
{
_server = new TcpListener(IPAddress.Any, port);
_server.Start();
_isRunning = true;
LoopClients();
}
public void LoopClients()
{
while (_isRunning)
{
// wait for client connection
TcpClient newClient = _server.AcceptTcpClient();
// client found.
// create a thread to handle communication
Thread t = new Thread(new ParameterizedThreadStart(HandleClient));
t.Start(newClient);
}
}
private byte[] ReadBytes(Stream s, int length)
{
byte[] bytes = new byte[length];
int read, total = 0;
while (total < length)
{
read = s.Read(bytes, total, length - total);
if (read == 0)
return null;
total += read;
}
return bytes;
}
private void SendBytes(Stream s, byte[] bytes)
{
int total = 0;
while (total < bytes.length)
{
total += s.Write(bytes, total, bytes.length - total);
}
}
private bool ReadUInt32(Stream s, out uint value)
{
byte[] bytes = ReadBytes(s, 4);
if (bytes == null)
return false;
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes);
value = BitConverter.ToUInt32(bytes, 0);
return true;
}
private void SendUInt32(Stream s, uint value)
{
byte[] bytes = BitConverter.GetBytes(value);
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes);
SendBytes(s, bytes);
}
private bool ReadString(Stream s, out string value)
{
value = "";
uint length;
if (!ReadUInt32(s, length))
return false;
if (length > 0)
{
byte[] bytes = ReadBytes(s, length);
if (bytes == null)
return false;
value = System.Text.Encoding.UTF8.GetString(bytes);
}
return true;
}
private void SendString(Stream s, string value)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(value);
SendUInt32(s, bytes.length);
SendBytes(s, bytes);
}
public void HandleClient(object obj)
{
// retrieve client from parameter passed to thread
TcpClient client = (TcpClient)obj;
Stream s = client.GetStream();
string data;
while (ReadString(s, data))
{
Console.WriteLine("Received: {0}", data);
// Process the data sent by the client.
data = data.ToUpper();
// Send back a response.
SendString(s, data);
Console.WriteLine("Sent: {0}", data);
}
}
}
namespace Multi_Threaded_TCP
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Multi-Threaded TCP Server Demo");
TcpServer server = new TcpServer(1111);
}
}
}
TestClient.cpp
#include <windows.h>
#include <winsock2.h>
#include <iostream>
#include <string>
#pragma comment(lib,"ws2_32.lib")
bool readRaw(SOCKET s, void *data, int len)
{
char *ptr = (char*) data;
while (len > 0)
{
int read = recv(s, ptr, len, 0);
if (read <= 0)
return false;
ptr += read;
len -= read;
}
return true;
}
bool sendRaw(SOCKET s, const void *data, int len)
{
const char *ptr = (const char*) data;
while (len > 0)
{
int sent = send(s, ptr, len, 0);
if (sent < 0)
return false;
ptr += sent;
len -= sent;
}
return true;
}
bool readUInt32(SOCKET s, ulong &value)
{
if (!readRaw(s, &value, sizeof(value)))
return false;
value = ntohl(value);
return true;
}
bool sendUInt32(SOCKET s, ulong value)
{
value = htonl(value);
return sendRaw(s, &value, sizeof(value));
}
bool readString(SOCKET s, std::wstring &str)
{
str.clear();
ulong utf8len;
if (!readUInt32(s, utf8len))
return false;
if (utf8len > 0)
{
std::string utf8;
utf8.resize(utf8len);
if (!readRaw(s, &utf8[0], utf8len))
return false;
int len = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), utf8.length(), NULL, 0);
if (len > 0)
{
str.resize(len);
MultiBytetoWideChar(CP_UTF8, 0, utf8.c_str(), utf8.length(), &str[0], len);
}
}
return true;
}
bool sendString(SOCKET s, const std::wstring &str)
{
std::string utf8;
int len = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0, NULL, NULL);
if (len > 0)
{
utf8.resize(len);
WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.length(), &utf8[0], len, NULL, NULL);
}
if (!sendUInt32(s, utf8.length()))
return false;
return sendRaw(s, utf8.c_str(), utf8.length());
}
int main()
{
//Winsock Startup
WSAData wsaData;
if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0) //If WSAStartup returns anything other than 0, then that means an error has occured in the WinSock Startup.
{
MessageBoxA(NULL, "Winsock startup failed", "Error", MB_OK | MB_ICONERROR);
return 1;
}
SOCKET Connection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //Set Connection socket
if (Connection == INVALID_SOCKET)
{
WSACleanup();
MessageBoxA(NULL, "Winsock socket failed", "Error", MB_OK | MB_ICONERROR);
return 1;
}
SOCKADDR_IN addr; //Address to be binded to our Connection socket
addr.sin_family = AF_INET; //IPv4 Socket
addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //Address = localhost (this pc)
addr.sin_port = htons(1111); //Port = 1111
if (connect(Connection, (SOCKADDR*)&addr, sizeof(addr)) != 0) //If we are unable to connect...
{
MessageBoxA(NULL, "Failed to Connect", "Error", MB_OK | MB_ICONERROR);
}
else
{
std::cout << "Connected!" << std::endl;
do
{
std::cout << "Enter a string to send:" << std::endl;
std::wstring msg;
if (!std::getline(std::wcin, msg))
break;
if (!sendString(Connection, msg))
{
MessageBoxA(NULL, "Failed to Send", "Error", MB_OK | MB_ICONERROR);
break;
}
if (!readString(Connection, msg))
{
MessageBoxA(NULL, "Failed to Read", "Error", MB_OK | MB_ICONERROR);
break;
}
std::wcout << "Received:" << std::endl << msg << std::endl;
}
while (true);
}
closesocket(Connection);
WSACleanup();
return 0;
}