gpt4 book ai didi

c# - 聊天服务应用

转载 作者:可可西里 更新时间:2023-11-01 02:52:33 25 4
gpt4 key购买 nike

我正在为游戏制作聊天服务,

我正在使用一个 TCP 监听器客户端获取帐户信息,某种登录服务。我想知道我是否可以让客户端连接到服务器,检查他是否仍然在线,并在他有新消息时继续向他发送消息。

我已经尝试为登录队列制作一个套接字列表,但是一旦我接受了一个新套接字,它就会断开之前的套接字与服务器的连接。

byte[] usernameByte = new byte[100];
int usernameRecieved = s.Receive(usernameByte);
//guiController.setText(System.DateTime.Now + " Recieved Login...");

byte[] passByte = new byte[100];
int passRecieved = s.Receive(passByte);
//guiController.setText(System.DateTime.Now + " Recieved Password...");

string username = "";
string password = "";

for (int i = 0; i < usernameRecieved; i++)
username += (Convert.ToChar(usernameByte[i]));

for (int i = 0; i < passRecieved; i++)
password += (Convert.ToChar(passByte[i]));

if (DomainController.getInstance().checkAccount(username, password))
{
ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes("true"));
s.Send(asen.GetBytes("U are succesfully logged in, press enter to continue"));
guiController.setText(serverName,System.DateTime.Now+"");
guiController.setText(serverName, "Sent Acknowledgement - Logged in");
}
else
{
ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes("false"));
s.Send(asen.GetBytes("U are NOT logged in, press enter to continue"));
guiController.setText(serverName, System.DateTime.Now + "");
guiController.setText(serverName, "\nSent Acknowledgement - Not logged in");
}

这是我目前用来检查用户发送给我的帐户信息的代码。在我发送此消息后,用户立即断开连接,我继续进行下一个连接。

我曾尝试制作 1 个单独的套接字列表并逐个处理它们,但失败了,因为前一个套接字的连接断开了,即使是 2 台不同的机器试图连接也是如此。

有没有人有解决方案/方法来保存套接字,我可以用它来让程序保持所有连接事件?这样我就可以从用户 1 向用户 2 发送消息,并且只使用他们连接的套接字?还是每次他们建立连接时我都需要添加一个 ID?

编辑

客户端代码:(这只是一个测试客户端)

while (true)
{
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("Connecting.....");
tcpclnt.Connect("xx.xxx.xxx.xx", 26862);
// use the ipaddress as in the server program

while(!(checkResponse(tcpclnt.GetStream())))
{
Thread.Sleep(1000);
}

Console.WriteLine("Connected");

Console.Write("Enter the string to be transmitted : ");

String str = Console.ReadLine();
if (str == "")
{
str = " ";
}

Stream stm = tcpclnt.GetStream();

ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes(str);


Console.WriteLine("Transmitting.....");

stm.Write(ba, 0, ba.Length);

Console.Write("Enter the string to be transmitted : ");

String str2 = Console.ReadLine();
if (str2 == "")
{
str2 = " ";
}

Stream stm2 = tcpclnt.GetStream();

ASCIIEncoding asen2 = new ASCIIEncoding();
byte[] ba2 = asen2.GetBytes(str2);


Console.WriteLine("Transmitting.....");

stm.Write(ba2, 0, ba2.Length);
if (str == "false")
{
blijvenWerken = false;
}
byte[] bb = new byte[100];
int k = stm.Read(bb, 0, 100);

for (int i = 0; i < k; i++)
Console.Write(Convert.ToChar(bb[i]));

byte[] bb2 = new byte[100];
int k2 = stm.Read(bb2, 0, 100);
Console.Write("\n");
for (int i = 0; i < k2; i++)
Console.Write(Convert.ToChar(bb2[i]));

Console.WriteLine("\n");

tcpclnt.Close();
Thread.Sleep(1000);
}

服务器获取套接字:这段代码在登录服务器上,因为我每次只能接受 1 个套接字以保持连接有效,所以我将 queueCount 设置为最大值 1。我希望能够列出我接受添加到用户帐户的套接字。

while (loginServerOn)
{
if (queueCount < 1)
{
if (loginServer.getLoginListener().Pending())
{
loginQueue.Add(loginServer.getSocket());
ASCIIEncoding asen = new ASCIIEncoding();
Socket s = loginQueue.First();
try
{
s.Send(asen.GetBytes("true"));
queueCount++;
}
catch
{
loginQueue.Remove(s);
}
}
}
}

返回接受套接字的函数。

public Socket getSocket()
{
return myList.AcceptSocket();
}

编辑:问题的本质

我想将收到的 socked 或 client 添加到我的 Account 对象中,因此每个连接都有一个链接到的 Account,当我想向某个帐户发送消息时,它应该向 socked 或 client bound 发送消息对于那个帐户,你能帮助/告诉我如何实现这一目标吗?

最佳答案

这仍然是 C# 和套接字,但我的方法与您的不同。

我采用了“connectedCleint”的概念,其目的类似于您所说的帐户。

我有一个名为 ServerTerminal 的类,它负责接受和顶层管理套接字连接。在这我有:

 public Dictionary<long, ConnectedClient> DictConnectedClients =
new Dictionary<long, ConnectedClient>();

所以这是我的由套接字句柄索引的已连接客户端列表。

接受连接我有一个例程:

public void StartListen(int port)
{
socketClosed = false;
IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, port);

listenSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);

//bind to local IP Address...
//if ip address is allready being used write to log
try
{
listenSocket.Bind(ipLocal);
}
catch (Exception excpt)
{
// Deal with this.. write your own log code here ?
socketClosed = true;

return;
}
//start listening...

listenSocket.Listen(100); // Max 100 connections for my app

// create the call back for any client connections...
listenSocket.BeginAccept(new AsyncCallback(OnClientConnection), null);

}

因此当客户端连接时它会触发:

private void OnClientConnection(IAsyncResult asyn)
{
if (socketClosed)
{
return;
}

try
{
Socket clientSocket = listenSocket.EndAccept(asyn);

ConnectedClient connectedClient = new ConnectedClient(clientSocket, this, _ServerTerminalReceiveMode);

//connectedClient.MessageReceived += OnMessageReceived;
connectedClient.Disconnected += OnDisconnection;
connectedClient.dbMessageReceived += OndbMessageReceived;

connectedClient.ccSocketFaulted += ccSocketFaulted;

connectedClient.StartListening();

long key = clientSocket.Handle.ToInt64();
if (DictConnectedClients.ContainsKey(connectedClient.SocketHandleInt64))
{
// Already here - use your own error reporting..
}

lock (DictConnectedClients)
{
DictConnectedClients[key] = connectedClient;
}

// create the call back for any client connections...
listenSocket.BeginAccept(new AsyncCallback(OnClientConnection), null);

}
catch (ObjectDisposedException excpt)
{
// Your own code here..
}
catch (Exception excpt)
{
// Your own code here...
}

}

这对你来说至关重要的部分是:

            // create the call back for any client connections...
listenSocket.BeginAccept(new AsyncCallback(OnClientConnection), null);

这将设置服务器终端以接收新连接。

编辑:减少我连接的客户端的版本:

public class ConnectedClient
{
private Socket mySocket;
private SocketIO mySocketIO;

private long _mySocketHandleInt64 = 0;


// These events are pass through; ConnectedClient offers them but really
// they are from SocketIO

public event TCPTerminal_ConnectDel Connected
{
add
{
mySocketIO.Connected += value;
}
remove
{
mySocketIO.Connected -= value;
}
}

public event TCPTerminal_DisconnectDel Disconnected
{
add
{
mySocketIO.Disconnected += value;
}
remove
{
mySocketIO.Disconnected -= value;
}
}

// Own Events

public event TCPTerminal_TxMessagePublished TxMessageReceived;

public delegate void SocketFaulted(ConnectedClient cc);
public event SocketFaulted ccSocketFaulted;

private void OnTxMessageReceived(Socket socket, TxMessage myTxMessage)
{
// process your message
}



private void OnMessageSent(int MessageNumber, int MessageType)
{
// successful send, do what you want..
}





public ConnectedClient(Socket clientSocket, ServerTerminal ParentST)
{
Init(clientSocket, ParentST, ReceiveMode.Handler);
}

public ConnectedClient(Socket clientSocket, ServerTerminal ParentST, ReceiveMode RecMode)
{
Init(clientSocket, ParentST, RecMode);
}

private void Init(Socket clientSocket, ServerTerminal ParentST, ReceiveMode RecMode)
{
ParentServerTerminal = ParentST;
_myReceiveMode = RecMode;

_FirstConnected = DateTime.Now;
mySocket = clientSocket;
_mySocketHandleInt64 = mySocket.Handle.ToInt64();
mySocketIO = new SocketIO(clientSocket, RecMode);

// Register for events
mySocketIO.TxMessageReceived += OnTxMessageReceived;
mySocketIO.MessageSent += OnMessageSent;
mySocketIO.dbMessageReceived += OndbMessageReceived;

}


public void StartListening()
{
mySocketIO.StartReceiving();
}

public void Close()
{
if (mySocketIO != null)
{
mySocketIO.Close();
mySocketIO = null;
}

try
{
mySocket.Close();
}
catch
{
// We're closing.. don't worry about it
}
}

public void SendMessage(int MessageNumber, int MessageType, string Message)
{
if (mySocket != null && mySocketIO != null)
{
try
{
mySocketIO.SendMessage(MessageNumber, MessageType, Message);
}
catch
{
// mySocketIO disposed inbetween check and call
}
}
else
{
// Raise socket faulted event
if (ccSocketFaulted != null)
ccSocketFaulted(this);
}
}


}

一些有用的链接:

这是我开始的地方: http://vadmyst.blogspot.com.au/2008/01/how-to-transfer-fixed-sized-data-with.html

http://vadmyst.blogspot.com.au/2008/03/part-2-how-to-transfer-fixed-sized-data.html

还有..

C# Sockets and Multithreading

Cause a connected socket to accept new messages right after .BeginReceive?

http://nitoprograms.blogspot.com.au/2009/04/tcpip-net-sockets-faq.html

http://www.codeproject.com/Articles/83102/C-SocketAsyncEventArgs-High-Performance-Socket-Cod

我现在不能发布我的整个解决方案;我需要调试的服务器代码存在缺陷;另外,有些部分我的雇主可能不想发表。但我的代码基于 Vadym 对可变长度消息的处理。

关于c# - 聊天服务应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14345860/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com