I am trying to listen for the client sending data multiple times. I do not know how to make the server listen to the client when the data is sent by the client a second time. For now i can send data by the client multiple times but the server will only accept the client data once. Please help.
Client
//the client
private TcpClient client = new TcpClient();
//constructor
public ClientConnect(string Ip, int Port)
{
IP = Ip;
PORT = Port;
}
//write the data to the server
public void Connect(byte[] clientId)
{
//try to connect to the server
Thread t = new Thread(() =>
{
while (true)
{
try
{
client.Connect(new IPEndPoint(IPAddress.Parse(IP), PORT));
break;
}
catch (SocketException)
{
Console.Clear();
Console.WriteLine("Trying to connect to the server...");
//pass if the connection failed
}
}
client.GetStream().Write(clientId, 0, (int)clientId.Length);
});
t.Start();
}
public void SendData(byte[] data)
{
Thread t2 = new Thread(() => {
while (true)
{
try
{
client.GetStream().Write(data, 0, (int)data.Length);
break;
}
catch (System.InvalidOperationException)
{
//pass
}
}
});
t2.Start();
}
Server:
while (true)
{
//Listen for a potential client
TcpClient client = tcpServer.AcceptTcpClient();
Console.WriteLine(client);
Console.WriteLine("Client connection accepted from " + client.Client.RemoteEndPoint + ".");
byte[] buffer = new byte[client.ReceiveBufferSize];
int bytesRead = client.GetStream().Read(buffer, 0, (int)buffer.Length);
byte[] buffer2 = new ArraySegment<byte>(buffer, 0, bytesRead).ToArray();
//do something with the data
}
Related
How I can to create python(or swift) TCP client for my TCP c# server?
c# API for my TCP server:
Client client = Client();
bool Connect()
{
UserInfo userInfo = new UserInfo("login", "pass");
NetworkConnectionParam connectionParams = new NetworkConnectionParam("127.0.0.1", 4021);
try
{
client.Connect(connectionParams,userInfo,ClientInitFlags.Empty);
}
catch
{
return false;
}
return client.IsStarted;
}
I try it(python) :
import socket
sock = socket.socket()
sock.connect(('localhost', 4021))
But I don't uderstand how I must to send my login and password (like in API for c#).
I don`t undestand what you want to implement.
If you want to run Python code in C#, then look at this IronPython
If you want to implement TCP client in C#, then try smth like this:
using System.Net;
using System.Net.Sockets;
class Program
{
static int port = 8005; // your port
static void Main(string[] args)
{
// get address to run socket
var ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
// create socket
var listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
// binding
listenSocket.Bind(ipPoint);
// start listen
listenSocket.Listen(10);
Console.WriteLine("Server is working");
while (true)
{
Socket handler = listenSocket.Accept();
// recieve message
StringBuilder builder = new StringBuilder();
int bytes = 0; // quantity of received bytes
byte[] data = new byte[256]; // data buffer
do
{
bytes = handler.Receive(data);
builder.Append(Encoding.Unicode.GetString(data, 0, bytes));
}
while (handler.Available>0);
Console.WriteLine(DateTime.Now.ToShortTimeString() + ": " + builder.ToString());
// send response
string message = "your message recieved";
data = Encoding.Unicode.GetBytes(message);
handler.Send(data);
// close socket
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
So I am working on creating my own proxy server for my game server.
Whats happening so far is that I try to connect to my Terraria server and it says
Connecting..
Then I start my server application which accepts incoming requests on that specific IP & port and it prompts a MessageBox saying"Connected" and then the game goes from "Connecting..." to "Connecting to server..." but it gets stuck there, this is most likely because I am not redirecting the traffic from my proxy server to my server.. Right?
I've been trying to .Write() to the stream but I think I am writing to the wrong stream, do I write to the stream that accepts connections or do I create a new stream for outgoing traffic?
public partial class MainWindow : Window
{
public static IPAddress remoteAddress = IPAddress.Parse("127.0.0.1");
public TcpListener remoteServer = new TcpListener(remoteAddress, 7777);
public TcpClient client = default(TcpClient);
public TcpClient RemoteClient = new TcpClient("terraria.novux.ru", 7777);
public MainWindow()
{
InitializeComponent();
}
private void BtnListen_OnClick(object sender, RoutedEventArgs e)
{
if (StartServer())
{
client = remoteServer.AcceptTcpClient();
MessageBox.Show("Connected");
var receivedBuffer = new byte[1024];
//Should I write to this one instead?
var clientStream = client.GetStream();
var stream = RemoteClient.GetStream();
while (client.Connected)
if (client.Connected)
if (client.ReceiveBufferSize > 0)
{
receivedBuffer = new byte[1024];
stream.Write(receivedBuffer, 0, receivedBuffer.Length);
}
}
}
private bool StartServer()
{
try
{
remoteServer.Start();
MessageBox.Show("Server Started...");
return true;
}
catch (Exception exception)
{
MessageBox.Show(exception.ToString());
throw;
}
}
}
A simplified implementation could look like this.
public class Program
{
public static void Main(string[] args)
{
StartTcpListener("localhost", 9000);
}
private static byte[] SendReceiveRemoteServer(string host, int port, byte[] data)
{
try
{
// Create a TcpClient.
// Note, for this client to work you need to have a TcpServer
// connected to the same address as specified by the server, port
// combination.
var client = new TcpClient(host, port);
// Get a client stream for reading and writing.
// Stream stream = client.GetStream();
var stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent to server: {0}", Encoding.ASCII.GetString(data));
// Receive the TcpServer.response.
// Read the first batch of the TcpServer response bytes.
var bytes = new byte[256];
var allBytes = new List<byte>();
var i = stream.Read(bytes, 0, bytes.Length);
// Loop to receive all the data sent by the client.
while (i != 0)
{
allBytes.AddRange(bytes);
bytes = new Byte[256];
i = stream.DataAvailable ? stream.Read(bytes, 0, bytes.Length) : 0;
}
Console.WriteLine("Received from server: {0}", Encoding.ASCII.GetString(data));
// Close everything.
stream.Close();
client.Close();
return allBytes.ToArray();
}
catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
Console.WriteLine("\n Press Enter to continue...");
return new byte[0];
}
private static void StartTcpListener(string host, int port)
{
TcpListener server = null;
try
{
var ipHostInfo = Dns.GetHostEntry(host);
var ipAddress = ipHostInfo.AddressList[0];
// TcpListener server = new TcpListener(port);
server = new TcpListener(ipAddress, port);
// Start listening for client requests.
server.Start();
// Enter the listening loop.
while (true)
{
Console.WriteLine("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
var client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
// Get a stream object for reading and writing
var stream = client.GetStream();
// Buffer for reading data
var bytes = new Byte[256];
var allBytes = new List<byte>();
var i = stream.Read(bytes, 0, bytes.Length);
// Loop to receive all the data sent by the client.
while (i != 0)
{
allBytes.AddRange(bytes);
bytes = new Byte[256];
i = stream.DataAvailable ? stream.Read(bytes, 0, bytes.Length) : 0;
}
if (allBytes.Count > 0)
{
Console.WriteLine("Received from client: {0}", Encoding.ASCII.GetString(allBytes.ToArray()));
var received = SendReceiveRemoteServer("localhost", 11000, allBytes.ToArray());
// Send back a response.
stream.Write(received, 0, received.Length);
Console.WriteLine("Sent to client: {0}", Encoding.ASCII.GetString(received));
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
Console.WriteLine("\nHit enter to continue...");
}
}
Although improvements should be made:
make it async
make it work with multiple TcpClients at the same time
I have some clients that connect to the server at the same time, and each of them send to server a registration message.
So, the messages collide with previous messages when they come to the server.
How can I manage the communications without collision between the messages?
I use asynchronous tcp socket in C#.
Here the server:
class ServerSocket
{
//The ClientInfo structure holds the required information about every
//client connected to the server
struct ClientInfo
{
public Socket socket; //Socket of the client
public string strName; //Name by which the user logged into the chat room
}
//The collection of all clients logged into the room (an array of type ClientInfo)
ArrayList clientList;
//The main socket on which the server listens to the clients
Socket serverSocket;
byte[] byteData = new byte[5000];
const int NUM_CLIENT = 12;
public ServerSocket()
{
clientList = new ArrayList();
}
public void LoadServer()
{
try
{
//We are using TCP sockets
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//Assign the any IP of the machine and listen on port number 1000
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 1000);
//Bind and listen on the given address
serverSocket.Bind(ipEndPoint);
serverSocket.Listen(NUM_CLIENT);
//Accept the incoming clients
serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);
Console.WriteLine("###################### S E R V E R ######################");
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void OnAccept(IAsyncResult ar)
{
try
{
Socket clientSocket = serverSocket.EndAccept(ar);
//Start listening for more clients
serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);
//Once the client connects then start receiving the commands from her
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnReceive), clientSocket);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void OnReceive(IAsyncResult ar)
{
string msgReceived = "";
try
{
Socket clientSocket = (Socket)ar.AsyncState;
clientSocket.EndReceive(ar);
msgReceived = GetString(byteData);
string strTemp = "";
for (int i = 0; i < msgReceived.IndexOf("<END>"); i++)
{
strTemp += msgReceived[i];
}
msgReceived = strTemp;
XmlBaseClientMsg xmlBaseClientMsg = new XmlBaseClientMsg();
BaseClientMsg baseClientMsgReceived = new BaseClientMsg();
baseClientMsgReceived = xmlBaseClientMsg.DeserializeFromString(msgReceived);
switch (baseClientMsgReceived.m_messageType)
{
case ClientMsgType.AI_REGISTRATION:
//When a user logs in to the server then we add him to our list of clients
ClientInfo AIClientInfo = new ClientInfo();
AIClientInfo.socket = clientSocket; // save the socket
AIClientInfo.strName = baseClientMsgReceived.m_sSenderID; // save the name of sender client
clientList.Add(AIClientInfo);
Console.WriteLine("The client: " + AIClientInfo.strName + " registered");
break;
case ClientMsgType.ENTITY_REGISTRATION:
//When a user logs in to the server then we add him to our list of clients
ClientInfo EntityClientInfo = new ClientInfo();
EntityClientInfo.socket = clientSocket; // save the socket
EntityClientInfo.strName = baseClientMsgReceived.m_sSenderID; // save the name of sender client
clientList.Add(EntityClientInfo);
Console.WriteLine("The client: " + EntityClientInfo.strName + " registered");
break;
#region
//case Command.Logout:
// //When a user wants to log out of the server then we search for her
// //in the list of clients and close the corresponding connection
// int nIndex = 0;
// foreach (ClientInfo client in clientList)
// {
// if (client.socket == clientSocket)
// {
// clientList.RemoveAt(nIndex);
// break;
// }
// ++nIndex;
// }
// clientSocket.Close();
// break;
#endregion
}
if (baseClientMsgReceived.m_messageType != ClientMsgType.AI_REGISTRATION)
{
Console.WriteLine("Type message: " + baseClientMsgReceived.m_messageType + " To: " +
baseClientMsgReceived.m_sReceiverID + " From: " + baseClientMsgReceived.m_sSenderID);
foreach (ClientInfo clientInfo in clientList)
{
if (clientInfo.strName == baseClientMsgReceived.m_sReceiverID)
{
byte[] message;
message = GetBytes(msgReceived);
// Send the message to reciever client
clientInfo.socket.BeginSend(message, 0, message.Length, SocketFlags.None,
new AsyncCallback(OnSend), clientInfo.socket);
Console.WriteLine("Msg No : " + baseClientMsgReceived.m_nMessageID + " Type: " + baseClientMsgReceived.m_messageType + " ==> has been sent");
break;
}
}
}
////If the user disconnects so no need to listen to him
// if (baseClientMsgReceived.m_messageType != ClientMsgType.Logout)
//{
//Start listening to the message send by the user
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnReceive), clientSocket);
//}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public void OnSend(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
client.EndSend(ar);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
}
class Program
{
public static int Main( String[] args )
{
ServerSocket serverSocket = new ServerSocket();
serverSocket.LoadServer();
while(true)
{
Console.ReadLine();
}
}
}
}
I'm trying to implement a small tcp based application in C#. I'm new to TCP programming.
The app is really simple. It's a client/server scenario, which support max 2 clients. One client will be an "external" IP, the other will be the host itself.
Everytime a client connect to the server, it begins to receive and send packets from/to the server.
I have set up a small console app which implements both TCP server side code and TCP client code.
The server use a listener binded to a specific port and wait for client connections. Once a client is connected, it spawn a new thread to handle communication with the client.
The client simply connect to the server and once the connection is estabilished it starts to receive and send pakcets.
As I said before "the host is also client of itself", but this leads to an issue. If the client send a packet to the server, both server and client claims to have received a packet. It is normal? Am I missing something?
UPDATE 2 (fixing issue)
I think I've found the issue. I need to "reset" the buffer once the send operation is done by the client
case SocketAsyncOperation.Send:
// Put in listen mode
// Buffer reset AFTER send and BEFORE receive
_receiver.SetBuffer(new byte[4096], 0, 4096);
_client.ReceiveAsync(_receiver);
break;
UPDATE 1 (adding code)
Server
public void Host()
{
_listener = new TcpListener(new IPEndPoint(IPAddress.Any, this.ConnectionPort));
_listener.Start();
this.IsListening = true;
ThreadPool.QueueUserWorkItem((state) =>
{
while (true)
{
// Blocks until a client connections occours
// If continue with no client then stop listening
try
{
TcpClient client = _listener.AcceptTcpClient();
// Add client to peer list
long assignedID = DateTime.UtcNow.Ticks;
_clients.Add(assignedID, client);
HandleClient(assignedID);
if (this.ConnectedClients == this.MaxClients)
{
_listener.Stop();
this.IsListening = false;
break;
}
}
catch
{
// Server has stop listening
_stopListen.Set();
break;
}
}
});
}
private void HandleClient(long assignedID)
{
ThreadPool.QueueUserWorkItem((state) =>
{
long clientID = (long)state;
TcpClient client = _clients[clientID];
try
{
byte[] message = new byte[4096];
byte[] buffer = new byte[4096];
int readed = 0;
int index = 0;
NetworkStream clientStream = client.GetStream();
while (true)
{
readed = clientStream.Read(message, 0, message.Length);
if (readed == 0)
{
// Client disconnected, thorw exception
throw new SocketException();
}
Array.Copy(message, 0, buffer, index, readed);
index += readed;
if (readed == 4096
&& !_packetHub.IsValidBufferData(buffer))
{
Array.Clear(buffer, 0, buffer.Length);
readed = 0;
index = 0;
continue;
}
if (_packetHub.IsValidBufferData(buffer))
{
NetPacket receivedPacket = _packetHub.DeserializePacket(buffer);
NetPacket answerPacket = null;
// Assign sender ID in case of unknown sender ID
if (receivedPacket.SenderID == NetPacket.UnknownID)
receivedPacket.SenderID = clientID;
// Handle received packet and forward answer packet
// to the client or to all other connected peers
answerPacket = HandlePacket(receivedPacket);
if (answerPacket != null)
{
if (answerPacket.RecipientID == clientID)
{
// Send answer packet to the client
SendPacket(client, answerPacket);
}
else
{
// Broadcast packet to all clients
foreach (TcpClient peer in _clients.Values)
SendPacket(peer, answerPacket);
}
}
// Reset receive packet buffer
Array.Clear(buffer, 0, buffer.Length);
readed = 0;
index = 0;
}
}
}
catch
{
System.Diagnostics.Debug.WriteLine("Network error occours!");
}
finally
{
// Close client connection
client.Close();
// Remove the client from the list
_clients.Remove(clientID);
// Raise client disconnected event
OnClientDisconnected();
}
}, assignedID);
}
Client
public void Connect()
{
if (this.ConnectionAddress == null)
throw new InvalidOperationException("Unable to connect. No server IP specified.");
_receiver = new SocketAsyncEventArgs();
_receiver.RemoteEndPoint = new IPEndPoint(this.ConnectionAddress, this.ConnectionPort);
_receiver.SetBuffer(new byte[4096], 0, 4096);
_receiver.Completed += new EventHandler<SocketAsyncEventArgs>(Socket_OperationComplete);
_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_client.ConnectAsync(_receiver);
}
private void Socket_OperationComplete(object sender, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
switch (e.LastOperation)
{
case SocketAsyncOperation.Connect:
_readyToSend = true;
this.IsConnected = true;
// Once connection is estabilished, send a join packet to
// retrive server side assigned informations
JoinPacket joinPacket = (JoinPacket)NetPacket.CreatePacket(this.ClientID, NetPacket.ToHost, NetPacket.JoinPacket);
joinPacket.ClientName = this.ClientName;
joinPacket.ClientAddress = this.LocalAddress.ToString();
SendPacket(joinPacket);
break;
case SocketAsyncOperation.Receive:
_readyToSend = true;
byte[] buffer = _receiver.Buffer;
System.Diagnostics.Debug.WriteLine("Client received packet (" + _packetHub.GetBufferDataType(buffer) + ") with length of: " + buffer.Length);
if (_packetHub.IsValidBufferData(buffer))
{
NetPacket receivedPacket = _packetHub.DeserializePacket(buffer);
NetPacket answerPacket = null;
// Handle received packet and forward answer packet
// to the server
answerPacket = HandlePacket(receivedPacket);
if (answerPacket != null)
SendPacket(answerPacket);
}
else
{
_client.ReceiveAsync(_receiver);
}
break;
case SocketAsyncOperation.Send:
// Put in listen mode
_client.ReceiveAsync(_receiver);
break;
}
}
else
{
OnClientDisconnected();
System.Diagnostics.Debug.WriteLine(String.Format("Network error: {0}", e.SocketError.ToString()));
}
}
Since you are using TCP, you have to specify a port to send/listen (different for server and client). So no, it isn't normal (but it is if client and server are sending/listening on the same port).
I am trying to establish a communication between a handheld and a PC.
I have the following code, for the client:
public void connect(string IPAddress, int port)
{
// Connect to a remote device.
try
{
IPAddress ipAddress = new IPAddress(new byte[] { 192, 168, 1, 10 });
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
if (connectDone.WaitOne()){
//do something..
}
else{
MessageBox.Show("TIMEOUT on WaitOne");
}
}
catch(Exception e){
MessageBox.Show(e.Message);
}
}
My problem is that when I run both of them in a pc they communicate fine, but the same code in a SmartDevice Project doesn't connect with the Server which is running on the PC and it give me this error:
System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or stablished connection failed
because connected host has failed to respond
What am I missing?
NOTE: The IPAddress is hard coded inside the code
EDIT: here is another code which I take from a MSDN example. This don't work either, it says that it not possible to read. The server code in this case is the same as the example, the client code have a modification:
private void button1_Click(object sender, EventArgs e)
{
// In this code example, use a hard-coded
// IP address and message.
string serverIP = "192.168.1.10";//HERE IS THE DIFERENCE
string message = "Hello";
Connect(serverIP, message);
}
Thanks in advance for any help!
For my "mobile device" client, I send data to the "PC" host using this:
private void Send(string value) {
byte[] data = Encoding.ASCII.GetBytes(value);
try {
using (TcpClient client = new TcpClient(txtIPAddress.Text, 8000)) {
NetworkStream stream = client.GetStream();
stream.Write(data, 0, data.Length);
}
} catch (Exception err) {
// Log the error
}
}
For the host, you're best to use a thread or BackgroundWorker where you can let a TcpListener object sit and wait:
private void Worker_TcpListener(object sender, DoWorkEventArgs e) {
BackgroundWorker worker = (BackgroundWorker)sender;
do {
string eMsg = null;
int port = 8000;
try {
_listener = new TcpListener(IPAddress.Any, port);
_listener.Start();
TcpClient client = _listener.AcceptTcpClient(); // waits until data is avaiable
int MAX = client.ReceiveBufferSize;
NetworkStream stream = client.GetStream();
Byte[] buffer = new Byte[MAX];
int len = stream.Read(buffer, 0, MAX);
if (0 < len) {
string data = Encoding.UTF8.GetString(buffer);
worker.ReportProgress(len, data.Substring(0, len));
}
stream.Close();
client.Close();
} catch (Exception err) {
// Log your error
}
if (!String.IsNullOrEmpty(eMsg)) {
worker.ReportProgress(0, eMsg);
}
} while (!worker.CancellationPending);
}