我正在做一个小游戏。 C ++上的服务器和基于C#的客户端。我有数据接收问题,我没有正确理解它是如何工作的,我需要第二个插座接收吗?或者第一个插座连接并可以同时接收?这是客户端
public class Connection
{
static private string ip = "127.0.0.1";
static private int port = 54000;
static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// static Socket acpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public static void connectToServer()
{
socket.Connect(ip, port);
}
public static void sendData(byte[] buffer)
{
socket.Send(buffer);
}
public static byte[] encodeMessage(string message)
{
byte[] bf = Encoding.ASCII.GetBytes(message);
return bf;
}
public static void recvData()
{
byte[] buf = new byte[256];
byte[] copy = new byte[256];
try
{
socket.Receive(buf);
}
catch (Exception e)
{
Console.WriteLine("Error");
}
if (buf != copy)
{
Console.WriteLine(Encoding.ASCII.GetChars(buf).ToString());
buf = copy;
}
}
}
这是服务器:
int main() {
//init sock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wsok = WSAStartup(ver, &wsData);
if (wsok != 0) {
cerr << "Error while init\n";
return 0;
}
//create
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET) {
cerr << "Error while creating\n";
return 0;
}
//bind
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
bind(listening, (sockaddr*)&hint, sizeof(hint));
//tell winsock that the socket is for listen
listen(listening, SOMAXCONN);
fd_set master;
FD_ZERO(&master);
FD_SET(listening, &master);
while (true) {
fd_set copy = master;
int socketCount = select(0, ©, nullptr, nullptr, nullptr);
for (int i = 0; i < socketCount; i++) {
SOCKET sock = copy.fd_array[i];
if (sock == listening) {
//accept connection
SOCKET client = accept(listening, nullptr, nullptr);
//add connection to list(&master)
FD_SET(client, &master);
//send welcome msg to connected client
string welcomeMsg = "Your connected!";
send(client, welcomeMsg.c_str(), welcomeMsg.size() + 1, 0);
}
else{
//accept message
char buf[32];
ZeroMemory(buf, 32);
string str;
int cnt = 0;
int bytesIn = recv(sock, buf, 32, 0);
for (int i = 0; i < sizeof(buf); i++) {
if (buf[i] != '0') {
content[cnt] = buf[i];
cnt++;
}
}
if (bytesIn <= 0) {
closesocket(sock);
FD_CLR(sock, &master);
}
else {
for (int i = 0; i < sizeof(buf); i++) {
cout << content[i];
}
for (int i = 0; i < master.fd_count; i++) {
SOCKET outSock = master.fd_array[i];
if (outSock != listening && outSock != sock) {
send(outSock, content, cnt, 0);
cout << "Message Send..." << endl;
}
}
}
}
}
}
我有计时器,我调用recvData()。问题是连接后它返回&#34;你已经连接了!&#34;但之后它只是卡住了,不起作用。如果我评论Socket.Receive我没有问题,但我需要这个接收。感谢
答案 0 :(得分:0)
您不必使用第二个套接字来接收数据,但Send
和Receive
是同步函数,因此线程会被阻塞,直到当前操作完成其工作。对于接收,套接字必须至少接收字节以便解除对应用程序的阻塞。如果没有可用数据,Receive
将无限期地等待,除非您使用ReceiveTimeout
属性指定超时。
要避免阻塞部分,请使用异步函数BeginReceive
和BeginSend
。 MSDN有一个完整的服务器 - 使用异步套接字的客户端示例。