I am currently trying to make a chess application with two clients and one server, lets say client1 and client2 are trying to speak to each other. the server side is ok but the client side is a little corrupted. The application has a chat part and when client1 wants to speak client2, client2 should receive the message immediately. When i put the BeginReceive line in a loop, client2 receives at the moment the message is sent but then connection problem occurs. If i dont make a loop with BeginReceive, then application has no errors but when client1 sends the message, client2 doesnt see the message immediately. Only when, client2 sends a message to client1, client1's first message is seen in the chat. can you help me about it?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
namespace ChessClient
{
public partial class Form1 : Form
{
private Socket client;
private byte[] data = new byte[1024];
private int size = 1024;
public Form1()
{
InitializeComponent();
sendbtn.Click += new EventHandler(ButtonSendOnClick);
connectbtn.Click += new EventHandler(ButtonConnectOnClick);
disconnectbtn.Click += new EventHandler(ButtonDisconOnClick);
}
void ButtonConnectOnClick(object obj, EventArgs ea)
{
conStatus.Text = "Connecting...";
Socket newsock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9060);
newsock.BeginConnect(iep, new AsyncCallback(Connected), newsock);
}
void ButtonSendOnClick(object obj, EventArgs ea)
{
byte[] message = Encoding.ASCII.GetBytes(chat.Text);
chat.Clear();
client.BeginSend(message, 0, message.Length, SocketFlags.None,
new AsyncCallback(SendData), client);
}
void ButtonDisconOnClick(object obj, EventArgs ea)
{
client.Close();
conStatus.Text = "Disconnected";
}
void Connected(IAsyncResult iar)
{
client = (Socket)iar.AsyncState;
try
{
client.EndConnect(iar);
conStatus.Text = "Connected to: " + client.RemoteEndPoint.ToString();
This is where i put inside the loop, beginreceive was in an infinite loop
client.BeginReceive(data, 0, size, SocketFlags.None,
new AsyncCallback(ReceiveData), client);
}
catch (SocketException)
{
conStatus.Text = "Error connecting";
}
}
void ReceiveData(IAsyncResult iar)
{
Socket remote = (Socket)iar.AsyncState;
int recv = remote.EndReceive(iar);
string stringData = Encoding.ASCII.GetString(data, 0, recv);
chatBox.Items.Add(stringData);
}
void SendData(IAsyncResult iar)
{
Socket remote = (Socket)iar.AsyncState;
remote.EndSend(iar);
remote.BeginReceive(data, 0, size, SocketFlags.None,
new AsyncCallback(ReceiveData), remote);
}
}
}
Related
System.Net.Sockets.SocketException (0x80004005): A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
I only get this error when trying to connect via my public IP, if I use localhost it works fine.
My code:
(Note: Public IP/Local IP and Port have been censored here, but I'm using my public IPV4 Address and a specific port which has been Port forwarded as well as allowed through my computers firewall both inbound and outbound)
(Client):
`
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
namespace RemoteBG
{
public partial class Form1 : Form
{
Socket client;
IPEndPoint remote;
public Form1()
{
InitializeComponent();
IPHostEntry host = Dns.GetHostEntry("PUBLICIP");
IPAddress ipAddress = host.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, PORT);
Socket sender = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
client = sender;
remote = remoteEP;
}
private void TextUpdate(String s)
{
textBox1.AppendText(s + System.Environment.NewLine);
}
private void button1_Click(object sender, EventArgs e)
{
byte[] bytes = new byte[1024];
try
{
// Connect to Remote EndPoint
client.Connect(remote);
Console.WriteLine("Socket connected to {0}",
client.RemoteEndPoint.ToString());
// Encode the data string into a byte array.
byte[] msg = Encoding.ASCII.GetBytes("This is a test<EOF>");
// Send the data through the socket.
int bytesSent = client.Send(msg);
// Receive the response from the remote device.
int bytesRec = client.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes, 0, bytesRec));
// Release the socket.
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
TextUpdate("Error connecting to Zang's PC. Error: " + se.ToString());
}
catch (Exception ex)
{
Console.WriteLine("Unexpected exception : {0}", ex.ToString());
}
}
private void button2_Click(object sender, EventArgs e)
{
}
}
}
Server:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace RemoteBGServer
{
class Program
{
public static int Main(String[] args)
{
StartServer();
return 0;
}
public static void StartServer()
{
IPHostEntry host = Dns.GetHostEntry("LOCALIP");
IPAddress ipAddress = host.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, PORT);
try
{
// Create a Socket that will use Tcp protocol
Socket listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
// A Socket must be associated with an endpoint using the Bind method
listener.Bind(localEndPoint);
// Specify how many requests a Socket can listen before it gives Server busy response.
// We will listen 10 requests at a time
listener.Listen(10);
Console.WriteLine("Waiting for a connection...");
Socket handler = listener.Accept();
// Incoming data from the client.
string data = null;
byte[] bytes = null;
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf("<EOF>") > -1)
{
break;
}
}
Console.WriteLine("Text received : {0}", data);
byte[] msg = Encoding.ASCII.GetBytes(data);
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\n Press any key to continue...");
Console.ReadKey();
}
}
}
`
Expected to see the test message "This is a test" instead got the exception.
This only occurs when using my public ip for IPHostEntry. Localhost works as expected.
Confirmed that the port is forwarded and firewall has exceptions for the port
i wrote a TCP server (Async Socket method in c# language) that can be get username and password from the clients, when one client connect and supply username and password everything will be work correctly and next users can store their username and password in a list, but when one client connect and then second client connect concurrently the second connected user's password take the place but with correct digit number of first client password;
the sequence events of environment
client1 connect;
client2 connect;
client1 enter username; (for example JOHN)
client2 enter username;(for example JACK)
client2 enter password;(for example 123456)
client1 enter password;(for example abc)
in the list is see;
list{
[0]:
username : JOHN
password : 123
[1]
username : JACK
password : 123456
}
as you see in above the first connected password is in correct size but with secondly connected clients password (which enter password earlier)
my codes is :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Collections.Concurrent;
namespace MyTestServer
{
class Program
{
public byte[] _buffer;
public byte[] _PASSBUFF;
private static Socket _ServerSocket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private List<SpecificClient> _ClientDirectory = new List<SpecificClient>();
static void Main(string[] args)
{
Console.Title = "Server";
Program SS = new Program();
SS.SetupServer();
//SetupServer();
Console.ReadLine();
}
private void SetupServer()
{
Console.WriteLine("Setting up server ...");
_ServerSocket.Bind(new IPEndPoint(IPAddress.Any, 100));
_ServerSocket.Listen(5);
_ServerSocket.BeginAccept(new AsyncCallback(AcceptCallBack), _ServerSocket);
}
private void AcceptCallBack(IAsyncResult AR)
{
Socket socket = _ServerSocket.EndAccept(AR);
_ServerSocket.BeginAccept(new AsyncCallback(AcceptCallBack), _ServerSocket);
Console.WriteLine("Client Connected");
string RequestForUsername = "Enter your username: ";
byte[] RFU_byte = Encoding.ASCII.GetBytes(RequestForUsername);
socket.BeginSend(RFU_byte, 0, RFU_byte.Length, SocketFlags.None, new AsyncCallback(onCompleteRequestForUsername), socket);
}
private void onCompleteRequestForUsername(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
socket.EndSend(AR);
_buffer = new byte[1024];
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(onUsernameReceived), socket);
}
private void onUsernameReceived(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
int RcvFromClient = socket.EndReceive(AR);
byte[] buffer = new byte[RcvFromClient];
Array.Copy(_buffer, buffer, buffer.Length);
string RcvUsername = Encoding.ASCII.GetString(buffer);
SpecificClient NewUser = new SpecificClient();
NewUser._username = RcvUsername;
NewUser._UserSocket = socket;
_ClientDirectory.Add(NewUser);
buffer = new byte[1024];
buffer = Encoding.ASCII.GetBytes("\r\nEnter your password: ");
socket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(onSendPropmtForPass), socket);
}
private void onSendPropmtForPass(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
socket.EndSend(AR);
_PASSBUFF = new byte[1024];
socket.BeginReceive(_PASSBUFF, 0, _PASSBUFF.Length, SocketFlags.None, new AsyncCallback(onReceivePassword), socket);
}
private void onReceivePassword(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
int ByteCountRcvPass = socket.EndReceive(AR);
byte[] PassBuff = new byte[ByteCountRcvPass];
Array.Copy(_PASSBUFF, PassBuff, PassBuff.Length);
string RcvPassword = Encoding.ASCII.GetString(PassBuff);
foreach ( SpecificClient Wanted in _ClientDirectory)
{
if (Wanted._UserSocket == socket)
{
Wanted._password = RcvPassword;
break;
}
}
}
}
}
I made a tcp/ip chat windows form application and it works just fine but I want to make the application to send the text automatically I don't want the user to click the send button like a live streaming!
and I am using Asynchronous connection.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
namespace Chat
{
public partial class Form1 : Form
{
Socket sck;
EndPoint epLocal, epRemote;
public Form1()
{
InitializeComponent();
sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sck.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
textBox1.Text = GetLocalIP();//this is where the application is running IP address
//textBox5.Text = GetLocalIP();
}
private string GetLocalIP()
{
IPHostEntry host;
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if(ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
return "127.0.0.1"; //here we put the android device's IP
}
private void MessageCallBack(IAsyncResult aResult)
{
try {
int size = sck.EndReceiveFrom(aResult, ref epRemote);
if(size>0)
{
byte[] receivedData = new byte[1464];
receivedData = (byte[])aResult.AsyncState;
ASCIIEncoding eEncoding = new ASCIIEncoding();
string receivedMessage = eEncoding.GetString(receivedData);
//b3deen bntba3 el msg bs b7aletna bdna n5li el touch active.
listBox1.Items.Add("Sender:" + receivedMessage);
}
byte[] buffer = new byte[1500];
sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer);
}
catch (Exception exp)
{
MessageBox.Show(exp.ToString());
}
}
private void button1_Click(object sender, EventArgs e)
{
try
{
//binding the message
epLocal = new IPEndPoint(IPAddress.Parse("192.168.1.9"), Convert.ToInt32("80"));
sck.Bind(epLocal);
//hoon el address ta3 el mobile
epRemote = new IPEndPoint(IPAddress.Parse("192.168.1.9"), Convert.ToInt32("81"));//texbox5 bn7at el ip ta3 el android wl txt el tani ta3 le port
//hoon bn3ml connect network
sck.Connect(epRemote);
byte[] buffer = new byte[1500];
sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer);
button1.Text = "Connected";
button1.Enabled = false;
button2.Enabled = true;
textBox3.Focus();
//trying to live sending
}
catch (Exception exp)
{
MessageBox.Show(exp.ToString());
}
}
private void button2_Click(object sender, EventArgs e)
{
try
{
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
byte[] msg = new byte[1500];
msg = enc.GetBytes(textBox3.Text);
sck.Send(msg);
listBox1.Items.Add("YOU:" + textBox3.Text);
}catch (Exception exp)
{
MessageBox.Show(exp.ToString());
}
// Close();
}
}
}
I assume that you want to send the text the user entered as he finished to type it. Even if I'd say this is a bad idea because it will confuse your users, you could add a timer which is counting the time since the user's last key stroke and if a given time was passed (let's say 5 secs), it invokes the method your button click is invoking as well to send the string.
Hey all I just find out what to do I wanted to send each string when its written so what i did I just handled the event for the textbox it self so when ever its changed it will send it right away :D good luck all :)
I've been playing with some c# socket code that I found at MSDN (original server code and client code) and I've run into a problem that I don't understand. First, here is my socket server code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace AsyncSocketServerTest
{
class Program
{
public class StateObject
{
public Socket socket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public List<byte> bytes = new List<byte>();
}
public static ManualResetEvent allDone = new ManualResetEvent(false);
private const string ipAdd = "127.0.0.1";
public static void StartListening()
{
byte[] bytes = new byte[1024];
IPAddress ipAddress = IPAddress.Parse(ipAdd);
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 25981);
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
allDone.Reset();
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static void AcceptCallback(IAsyncResult ar)
{
allDone.Set();
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
StateObject state = new StateObject();
state.socket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
public static void ReadCallback(IAsyncResult ar)
{
Console.WriteLine("Inside ReadCallback()...");
// retrieve the state object and the handler socket from the asynchronous state object
StateObject state = (StateObject)ar.AsyncState;
Socket socket = state.socket;
// read data from the client socket
int bytesRead = socket.EndReceive(ar);
if (bytesRead > 0)
{
// there might be more data, so store the data received so far
for (int bufferIndex = 0; bufferIndex < bytesRead; bufferIndex++)
{
state.bytes.Add(state.buffer[bufferIndex]);
}
socket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
else
{
if (state.bytes.Count > 0)
{
// All the data has been read from the client; display it on the console.
byte[] bytesReceived = state.bytes.ToArray();
Console.WriteLine("Received {0} bytes from client...", bytesReceived.Length.ToString());
}
// generate a 50 byte response to send back to the client
Random r = new Random();
byte[] responseToSend = new byte[50];
r.NextBytes(responseToSend);
// *** THIS APPEARS TO BE CAUSING A PROBLEM ***
// send the response back to client
SendBytes(socket, responseToSend);
// ********************************************
// edit - commented out; the socket shouldn't be closed before the response is sent back to the client asynchronously
//socket.Close();
}
}
private static void SendBytes(Socket client, byte[] bytesToSend)
{
client.BeginSend(bytesToSend, 0, bytesToSend.Length, 0, new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
Socket handler = (Socket)ar.AsyncState;
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
static void Main(string[] args)
{
StartListening();
Console.ReadKey();
}
}
}
And now for the client code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace AsyncSocketClientTest
{
class Program
{
public class StateObject
{
public Socket socket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public List<byte> bytes = new List<byte>();
}
private const string ipAdd = "127.0.0.1";
// ManualResetEvent instances signal completion
private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false);
private static void StartClient()
{
try
{
IPAddress ipAddress = IPAddress.Parse(ipAdd);
IPEndPoint remoteEndPoint = new IPEndPoint(ipAddress, 25981);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.BeginConnect(remoteEndPoint, new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
// generate 100 random bytes to send to the server
Random r = new Random();
byte[] buffer = new byte[100];
r.NextBytes(buffer);
// send data to the server
SendBytes(client, buffer);
sendDone.WaitOne();
// *** THIS APPEARS TO BE CAUSING A PROBLEM ***
// receive the response from the remote host
ReceiveBytes(client);
receiveDone.WaitOne();
// ********************************************
// release the socket
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
// retrieve the socket from the state object
Socket client = (Socket)ar.AsyncState;
// complete the connection
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString());
// signal that the connection has been made
connectDone.Set();
}
catch (SocketException sockEx)
{
// if the server isn't running, we're going to get a socket exception here...
Console.WriteLine(sockEx.Message);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveBytes(Socket client)
{
Console.WriteLine("Inside ReceiveBytes()...");
try
{
// create the state object
StateObject state = new StateObject();
state.socket = client;
// begin receiving data from the remote device
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
Console.WriteLine("Inside ReceiveCallback()...");
try
{
// Retrieve the state object and the client socket from the asynchronous state object
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.socket;
// Read data from the remote host
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
// there might be more data, so store the data received so far
for (int bufferIndex = 0; bufferIndex < bytesRead; bufferIndex++)
{
state.bytes.Add(state.buffer[bufferIndex]);
}
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
else
{
if (state.bytes.Count > 0)
{
// All the data has been read from the client; display it on the console.
byte[] bytesReceived = state.bytes.ToArray();
Console.WriteLine("Read {0} bytes from socket...", bytesReceived.Length.ToString());
}
// Signal that all bytes have been received
receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void SendBytes(Socket client, byte[] bytesToSend)
{
// Begin sending the data to the remote device
client.BeginSend(bytesToSend, 0, bytesToSend.Length, 0, new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// retrieve the socket from the state object
Socket client = (Socket)ar.AsyncState;
// complete sending the data to the remote device
int bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
// signal that all bytes have been sent
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
static void Main(string[] args)
{
StartClient();
}
}
}
If I comment out the code in the client that receives the response back from the server as well as the code in the server that attempts to send the response to the client, then things appear to be working as you would expect (i.e., the client connects to the server, sends data and the server receives the data properly). When I uncomment these sections of the code, however, I'm seeing some behavior that I don't understand. In this case, I see the client connect to the server and send data to it. On the server side, the code appears to hang inside ReadCallback(). To better illustrate this, when the code sections I mentioned previously are commented out, I see this:
Client output:
Socket connected to 127.0.0.1:25981
Sent 100 bytes to server.
Server output:
Waiting for a connection...
Waiting for a connection...
Inside ReadCallback()...
Inside ReadCallback()...
Received 100 bytes from client...
As you can see from this output, when the server receives the 100 bytes of client data, I see two calls to ReadCallback(). So now I uncomment the aforementioned code and run it again. This time, I see:
Client output:
Socket connected to 127.0.0.1:25981
Sent 100 bytes to server.
Inside ReceiveBytes()...
Server output:
Waiting for a connection...
Waiting for a connection...
Inside ReadCallback()...
This time, my client sends 100 bytes of data to the server, sets the sendDone ManualResetEvent and then goes into ReceiveBytes(). On the server side, I see a single call to ReadCallback() and nothing else. That leads me to believe that the server didn't properly finish reading the data from the client although I'm not sure why. What am I missing?
This doesn't really answer your exact question but may I suggest an alternate way to go about this? For me threads are a bit easier to understand and the code looks a bit cleaner:
Server
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication2 {
class Program {
static void Main(string[] args) {
ServerWorkThread objThread = new ServerWorkThread();
while(true) {
objThread.HandleConnection(objThread.mySocket.Accept());
}
}
}
public class ServerWorkThread {
public Socket mySocket;
public ServerWorkThread() {
IPEndPoint objEnpoint = new IPEndPoint(IPAddress.Parse("***.***.***.***"), 8888);
mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
mySocket.Bind(objEnpoint);
mySocket.Listen(100);
}
public void HandleConnection(Socket iIncomingSocket) {
Thread worker = new Thread(this.RecieveAndSend);
worker.Start(iIncomingSocket);
worker.Join();
}
public void RecieveAndSend(object iIncoming) {
Socket objSocket = (Socket)iIncoming;
byte[] bytes = new byte[1024];
int bytesRecieved = objSocket.Receive(bytes);
string strReceived = System.Text.Encoding.ASCII.GetString(bytes, 0, bytesRecieved);
Console.WriteLine("Received from client: " + strReceived);
Console.WriteLine("Sending acknowledgement to client");
string strSend = ("Command of: " + strReceived + " was processed successfully");
objSocket.Send(System.Text.Encoding.ASCII.GetBytes(strSend));
objSocket.Close();
}
}
}
Client:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Client {
class Program {
static void Main(string[] args) {
ClientWorkThread thread1 = new ClientWorkThread("I am thread 1");
thread1.SendCommand();
ClientWorkThread thread2 = new ClientWorkThread("I am thread 2");
thread2.SendCommand();
ClientWorkThread thread3 = new ClientWorkThread("I am thread 3");
thread3.SendCommand();
Console.Read();
}
}
public class ClientWorkThread {
private Socket pSocket;
private string command;
public ClientWorkThread(string iCommand) {
IPEndPoint objEnpoint = new IPEndPoint(IPAddress.Parse("***.***.***.***"), 8888);
pSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
pSocket.Connect(objEnpoint);
command = iCommand;
}
public void SendCommand() {
Thread worker = new Thread(this.Send);
worker.Start(pSocket);
}
public void Send(object iSending) {
Socket objSocket = (Socket)iSending;
objSocket.Send(System.Text.Encoding.ASCII.GetBytes(command + " now DO WORK "));
Console.WriteLine("Sending: " + command + " now DO WORK ");
byte[] bytes = new byte[1024];
int bytesRecieved = objSocket.Receive(bytes);
string strReceived = System.Text.Encoding.ASCII.GetString(bytes, 0, bytesRecieved);
Console.WriteLine("Received from server: " + strReceived);
objSocket.Close();
}
}
}
Server output:
Received from client: I am thread 1 now DO WORK
Sending acknowledgement to client
Received from client: I am thread 2 now DO WORK
Sending acknowledgement to client
Received from client: I am thread 3 now DO WORK
Sending acknowledgement to client
Client output:
Sending: I am thread 2 now DO WORK
Sending: I am thread 3 now DO WORK
Received from server: Command of: I am thread 2 now DO WORK was processed successfully
Received from server: Command of: I am thread 3 now DO WORK was processed successfully
Sending: I am thread 1 now DO WORK
Received from server: Command of: I am thread 1 now DO WORK was processed successfully
You could also use thread.Join() to have them finish executing in order.
I have made a connection between server and client, the client send data to the server and receive a response, but i wanna send data from the server to client and receive the response from client to server, is it possible ? Here is my code :
[Client] :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace Multi_Client
{
class Program
{
private static Socket _clientSocket = new Socket
(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
static void Main(string[] args)
{
Console.Title = "Client";
ConnectToServer();
RequestLoop();
Exit();
}
private static void ConnectToServer()
{
int attempts = 0;
while (!_clientSocket.Connected)
{
try
{
attempts++;
Console.WriteLine("Connection attempt " + attempts);
_clientSocket.Connect(IPAddress.Loopback, 100);
}
catch (SocketException)
{
Console.Clear();
}
}
Console.Clear();
Console.WriteLine("Connected");
_clientSocket.Send(Encoding.ASCII.GetBytes("C1"));
}
private static void RequestLoop()
{
Console.WriteLine(#"<Type ""exit"" to properly disconnect client>");
SendRequest();
ReceiveResponse();
}
/// <summary>
/// Close socket and exit app
/// </summary>
private static void Exit()
{
SendString("exit"); // Tell the server we re exiting
_clientSocket.Shutdown(SocketShutdown.Both);
_clientSocket.Close();
Environment.Exit(0);
}
private static void SendRequest()
{
Console.Write("Send a request: ");
string request = Console.ReadLine();
SendString(request);
if (request.ToLower() == "exit")
{
Exit();
return;
}
}
private static void SendString(string text)
{
byte[] buffer = Encoding.ASCII.GetBytes(text);
_clientSocket.Send(buffer, 0, buffer.Length, SocketFlags.None);
}
private static void ReceiveResponse()
{
byte[] buffer = new byte[2048];
int received = _clientSocket.Receive(buffer, SocketFlags.None);
if (received == 0) return;
byte[] data = new byte[received];
Array.Copy(buffer, data, received);
string text = Encoding.ASCII.GetString(data);
Console.WriteLine(text);
}
}
}
[Server] :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.IO;
using NetworkCommsDotNet;
using System.Net.Sockets;
namespace Server
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private static Socket _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private static List<Socket> _clientSockets = new List<Socket>();
private static readonly int _BUFFER_SIZE = 2048;
private static byte[] _buffer = new byte[_BUFFER_SIZE];
string text;
Socket current;
Socket test;
delegate void SetTextCallback(string text);
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.richTextBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.richTextBox1.Text += text + "\n";
}
}
private void SetupServer()
{
SetText("Setting up server...");
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, 100));
_serverSocket.Listen(5);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
SetText("Server Setup");
}
/// <summary>
/// Close all connected client (we do not need to shutdown the server socket as its connections
/// are already closed with the clients)
/// </summary>
private static void CloseAllSockets()
{
foreach (Socket socket in _clientSockets)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
_serverSocket.Close();
}
private void AcceptCallback(IAsyncResult AR)
{
Socket socket = null;
try
{
socket = _serverSocket.EndAccept(AR);
}
catch (ObjectDisposedException) // I cannot seem to avoid this (on exit when properly closing sockets)
{
return;
}
_clientSockets.Add(socket);
socket.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
SetText("Client connected, waiting for request...");
test = (Socket)AR.AsyncState;
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
private void ReceiveCallback(IAsyncResult AR)
{
current = (Socket)AR.AsyncState;
int received = 0;
try
{
received = current.EndReceive(AR);
}
catch (SocketException)
{
SetText("Client forcefully disconnected");
current.Close(); // Dont shutdown because the socket may be disposed and its disconnected anyway
_clientSockets.Remove(current);
return;
}
byte[] recBuf = new byte[received];
Array.Copy(_buffer, recBuf, received);
text = Encoding.ASCII.GetString(recBuf);
SetText("Received Text: " + text);
if (text.ToLower() == "get tim") // Client requested time
{
SetText("Text is a get time request");
byte[] data = Encoding.ASCII.GetBytes(DateTime.Now.ToLongTimeString());
current.Send(data);
SetText("Time sent to client");
}
else if (text.ToString() == "C1") // Client wants to exit gracefully
{
SetText("Received :: C1");
byte[] data = Encoding.ASCII.GetBytes(DateTime.Now.ToLongTimeString());
current.Send(data);
}
else
{
SetText("Server is sending invalid packet");
SetText("Warning Sent");
}
current.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, new AsyncCallback(ReceiveCallback), current);
}
private void Form1_Load(object sender, EventArgs e)
{
SetupServer();
}
private void Send_Received(string mess)
{
byte[] data = Encoding.ASCII.GetBytes(mess);
test.Send(data);
}
private void button2_Click(object sender, EventArgs e)
{
CloseAllSockets();
}
private void button1_Click(object sender, EventArgs e)
{
Send_Received(textBox1.Text);
}
}
}
Short answer: Yes, it is possible.
Long aswer: Yes. Your current code is implemented this way:
Server initializes and prepares to receive connections.
Client tries to connect.
Server accepts connection, adds to clientSockets collection.
Client sends "C1".
Server receives content, interprets, and send answer back.
Client receives answer.
And then you enter a loop, since no other content is sent. You implemented a synchronous protocol - client talks, server talks back, client dumps it to console.
Let me suggest a quick implementation so you can test a server->client->server exchange:
Implement an asynchronous timer on your server.
After 10 seconds, if no incoming message arrives from an specific client, send a "PING?" message to it.
Parse the incoming content on the client. If the message is equal to "PING?", answer with a "PONG!".
This is a very simple QoS protocol - you'll be testing the connection's health.
Let us know if you manage to implement it. =)
Actually, i know where is the problem, when the server send something to the client and the client hasn't already sent something, the client doesn't show the thing until he sent another stuff :O
Example (i know it's complicated) :
Server sent C1 and show in the console C1 sent to client : Client do nothing (he should show in the console C1O)
Client sent Pa (random) and show in the console CAO : Server receive Pa
Client sent Ka (random) and show in the console (Invalid request because the server has received Pa so it sends invalid request text)
I hope that it's clean even if i knew that it's not :S
I resolved it by editing the RequestLoop function :
private static void RequestLoop()
{
ReceiveResponse();
}
It`s all :)