I am working on a project where I am going to create a TCP/IP Chat application and I have some problems with passing variables between the classes. The variable data does not get passed on from the handleClient to the main class where data along with clientSocket is saved to a Hashtable. The Hashtable is later going to be used for broadcasting the message to all clients. The error i get is as follows: "Error: The name 'data' does not exist in the current context"
Serverside code:
using System;
using System.IO;
using System.Data;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Collections;
namespace Chat_server
{
public class Program
{
//Creates a list with all clients
public static Hashtable clientList = new Hashtable();
public void Main(string[] args)
{
TcpListener serverSocket = null;
// Set the TcpListener on port 13000.
Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
// TcpListener server = new TcpListener(port);
serverSocket = new TcpListener(localAddr, port);
// Start listening for client requests.
serverSocket.Start();
int counter = 0;
while (true)
{
counter += 1;
Console.WriteLine("Waiting for a connection... ");
TcpClient clientSocket = serverSocket.AcceptTcpClient();
clientList.Add(data, clientSocket);
Console.WriteLine(" >> " + "Client No:" + Convert.ToString(counter) + " started!");
handleClient hclient = new handleClient();
hclient.startClient(clientSocket);
}
}
}
}
//Class to handle each connection separatly
public class handleClient
{
TcpClient clientSocket;
Hashtable clientList;
public void startClient(TcpClient inClient)
{
this.clientSocket = inClient;
Thread clientThread = new Thread(new ThreadStart(doChat));
clientThread.Start();
}
public void doChat()
{
Byte[] bytes = new Byte[10025];
String data = null;
data = null;
while ((true))
{
try
{
foreach (DictionaryEntry Item in clientList)
{
data = null;
// Get a stream object for reading and writing
NetworkStream stream = clientSocket.GetStream();
int i;
// Loop to receive all the data sent by the client.
while ((i = stream.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);
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
// Send back a response.
stream.Write(msg, 0, msg.Length);
stream.Flush();
Console.WriteLine("Sent: {0}", data);
}
// Shutdown and end connection
clientSocket.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
}
}
}
}
data isn't defined in that function or in the class at:
clientList.Add(data, clientSocket);
Related
So this is my basic chat program which allows user to add its own IP and receive an IP, plus custom ports to communicate.
In the windows forms design I have:
Textbox --- textLocalIp
Textbox --- textLocalPort
Textbox --- textFriendIp
Textbox --- textFriendPort
Textbox --- textMessage
Listbox --- listMessage
Button --- Start
Button --- Send
So this is a very basic client but what I want help with is making it secure/more secure because security right now is not good.
Maybe like a tunnel with different IP's so that you don't have to know the receivers IP, just a IP they provide which then sends it to them or whatever?
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 Client
{
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);
textLocalIp.Text = GetLocalIP();
textFriendIp.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";
}
private void MessageCallBack(IAsyncResult aResult)
{
try
{
int size = sck.EndReceiveFrom(aResult, ref epRemote);
if (size > 0)
{
byte[] recievedData = new byte[1464];
recievedData = (byte[])aResult.AsyncState;
ASCIIEncoding eEncoding = new ASCIIEncoding();
string receivedMessage = eEncoding.GetString(recievedData);
listMessage.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
{
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
byte[] msg = new byte[1500];
msg = enc.GetBytes(textMessage.Text);
sck.Send(msg);
listMessage.Items.Add("Local:" + textMessage.Text);
textMessage.Clear();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void start_Click(object sender, EventArgs e)
{
try
{
epLocal = new IPEndPoint(IPAddress.Parse(textLocalIp.Text), Convert.ToInt32(textLocalPort.Text));
sck.Bind(epLocal);
epRemote = new IPEndPoint(IPAddress.Parse(textFriendIp.Text), Convert.ToInt32(textFriendPort.Text));
sck.Connect(epRemote);
byte[] buffer = new byte[1500];
sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer);
start.Text = "Connected";
start.Enabled = false;
send.Enabled = true;
textMessage.Focus();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
It is more difficult to implement socket communication security using channels. So I suggest you encrypt the IP and transmission content.
For IP encryption, you can set the Passwordchar attribute of the TextBox to *.
For transmission content, you can encrypt it with an encryption algorithm.
The following code implements the communication between a server and multiple clients, and you can perform encryption on this basis.
Server:
namespace Server
{
class Program
{
private static byte[] result = new byte[1024];
private static int myProt = 8885;
static Socket serverSocket;
static void Main(string[] args)
{
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(new IPEndPoint(IPAddress.Any, myProt));
serverSocket.Listen(10); //Set up to 10 queued connection requests
Console.WriteLine("Start listening {0} successfully", serverSocket.LocalEndPoint.ToString());
Thread myThread = new Thread(ListenClientConnect);
myThread.Start();
Console.ReadLine();
}
/// <summary>
/// Listen for Client connections
/// </summary>
private static void ListenClientConnect()
{
while (true)
{
Socket clientSocket = serverSocket.Accept();
clientSocket.Send(Encoding.ASCII.GetBytes("Server Say Hello"));
Thread receiveThread = new Thread(ReceiveMessage);
receiveThread.Start(clientSocket);
}
}
/// <summary>
/// receive data
/// </summary>
/// <param name="clientSocket"></param>
private static void ReceiveMessage(object clientSocket)
{
Socket myClientSocket = (Socket)clientSocket;
while (true)
{
try
{
int receiveNumber = myClientSocket.Receive(result);
Console.WriteLine("Receive client {0} message {1}", myClientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result, 0, receiveNumber));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
myClientSocket.Shutdown(SocketShutdown.Both);
myClientSocket.Close();
break;
}
}
}
}
}
Client:
namespace Client
{
class Program
{
private static byte[] result = new byte[1024];
static void Main(string[] args)
{
IPAddress ip = IPAddress.Parse("127.0.0.1");
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
clientSocket.Connect(new IPEndPoint(ip, 8885));
Console.WriteLine("Successfully connected to the server");
}
catch
{
Console.WriteLine("Failed to connect to the server, please press Enter to exit!");
return;
}
//Receive data through clientSocket
int receiveLength = clientSocket.Receive(result);
Console.WriteLine("Server:{0}", Encoding.ASCII.GetString(result, 0, receiveLength));
//Send data through clientSocket
for (int i = 0; i <3; i++)
{
try
{
Thread.Sleep(1000);
string sendMessage = "client send Message Hellp" + DateTime.Now;
clientSocket.Send(Encoding.ASCII.GetBytes(sendMessage));
Console.WriteLine("Client:{0}" + sendMessage);
}
catch
{
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
break;
}
}
Console.WriteLine("After sending, press Enter to exit");
Console.ReadLine();
}
}
}
I'll cut to the point, I've been stuck on this for a few hours now. Tons of Google and tons of research but not straight answer as of yet.
I have a client and a server coded for TCP which functions perfectly fine, however, I want the client to also be able to use UDP with the server for none-important packets such as player location.
As of right now, this is my connect code for connected clients.
public void ConnectToServer(){
tcp_client = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
tcp_client.Connect(server_ip, server_port);
tcp_stream = new NetworkStream(this.tcp_client);
this.udp_client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
this.udp_client.BeginConnect(IPAddress.Parse(server_ip), server_port,new AsyncCallback(udp_connected), null);
}
Now the client isn't what I've had issues with for when I use udp.Send(byteArray) it appears to be sending as it's not throwing any exceptions but the server itself isn't responding to any data received.
Please Note this is NOT 100% copy/pasted code. Alter to show just what's being an issue.
private Socket c;
private UdpClient udp;
private isRunning = true;
public Client(Socket c){
// This was accepted from TcpListener on Main Server Thread.
this.c = c;
this.networkStream = new NetworkStream(this.c);
udp = new UdpClient();
udp.Connect((IPEndPoint)c.RemoteEndPoint);
// Then starts 2 thread for listening, 1 for TCP and 1 for UDP.
}
private void handleUDPTraffic(){
IPEndPoint groupEP = (IPEndPoint)c.RemoteEndPoint;
while (isRunning){
try{
byte[] udp_received = udp.Receive(ref groupEP);
Console.WriteLine("Received UDP Packet Data: " + udp_received.Length);
}catch{
log.ERROR("UDP", "Couldn't Receive Data...");
}
}
}
You can use both TCP and UDP on the same port. See also:
Can TCP and UDP sockets use the same port?
The sample below demonstrates that, you can simultaneously send and receive UDP and TCP messages.
Maybe, your UdpClient creation to listen for incoming datagrams is the problem. I recommend to create it once like your TcpListener.
The servers:
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 TCPUDPServer
{
class Program
{
static void Main(string[] args)
{
TcpListener tcpServer = null;
UdpClient udpServer = null;
int port = 59567;
Console.WriteLine(string.Format("Starting TCP and UDP servers on port {0}...", port));
try
{
udpServer = new UdpClient(port);
tcpServer = new TcpListener(IPAddress.Any, port);
var udpThread = new Thread(new ParameterizedThreadStart(UDPServerProc));
udpThread.IsBackground = true;
udpThread.Name = "UDP server thread";
udpThread.Start(udpServer);
var tcpThread = new Thread(new ParameterizedThreadStart(TCPServerProc));
tcpThread.IsBackground = true;
tcpThread.Name = "TCP server thread";
tcpThread.Start(tcpServer);
Console.WriteLine("Press <ENTER> to stop the servers.");
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("Main exception: " + ex);
}
finally
{
if (udpServer != null)
udpServer.Close();
if (tcpServer != null)
tcpServer.Stop();
}
Console.WriteLine("Press <ENTER> to exit.");
Console.ReadLine();
}
private static void UDPServerProc(object arg)
{
Console.WriteLine("UDP server thread started");
try
{
UdpClient server = (UdpClient)arg;
IPEndPoint remoteEP;
byte[] buffer;
for(;;)
{
remoteEP = null;
buffer = server.Receive(ref remoteEP);
if (buffer != null && buffer.Length > 0)
{
Console.WriteLine("UDP: " + Encoding.ASCII.GetString(buffer));
}
}
}
catch (SocketException ex)
{
if(ex.ErrorCode != 10004) // unexpected
Console.WriteLine("UDPServerProc exception: " + ex);
}
catch (Exception ex)
{
Console.WriteLine("UDPServerProc exception: " + ex);
}
Console.WriteLine("UDP server thread finished");
}
private static void TCPServerProc(object arg)
{
Console.WriteLine("TCP server thread started");
try
{
TcpListener server = (TcpListener)arg;
byte[] buffer = new byte[2048];
int count;
server.Start();
for(;;)
{
TcpClient client = server.AcceptTcpClient();
using (var stream = client.GetStream())
{
while ((count = stream.Read(buffer, 0, buffer.Length)) != 0)
{
Console.WriteLine("TCP: " + Encoding.ASCII.GetString(buffer, 0, count));
}
}
client.Close();
}
}
catch (SocketException ex)
{
if (ex.ErrorCode != 10004) // unexpected
Console.WriteLine("TCPServerProc exception: " + ex);
}
catch (Exception ex)
{
Console.WriteLine("TCPServerProc exception: " + ex);
}
Console.WriteLine("TCP server thread finished");
}
}
}
The clients:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace TCPUDPClient
{
class Program
{
static void Main(string[] args)
{
UdpClient udpClient = null;
TcpClient tcpClient = null;
NetworkStream tcpStream = null;
int port = 59567;
ConsoleKeyInfo key;
bool run = true;
byte[] buffer;
Console.WriteLine(string.Format("Starting TCP and UDP clients on port {0}...", port));
try
{
udpClient = new UdpClient();
udpClient.Connect(IPAddress.Loopback, port);
tcpClient = new TcpClient();
tcpClient.Connect(IPAddress.Loopback, port);
while(run)
{
Console.WriteLine("Press 'T' for TCP sending, 'U' for UDP sending or 'X' to exit.");
key = Console.ReadKey(true);
switch (key.Key)
{
case ConsoleKey.X:
run = false;
break;
case ConsoleKey.U:
buffer = Encoding.ASCII.GetBytes(DateTime.Now.ToString("HH:mm:ss.fff"));
udpClient.Send(buffer, buffer.Length);
break;
case ConsoleKey.T:
buffer = Encoding.ASCII.GetBytes(DateTime.Now.ToString("HH:mm:ss.fff"));
if (tcpStream == null)
tcpStream = tcpClient.GetStream();
tcpStream.Write(buffer, 0, buffer.Length);
break;
}
}
}
catch (Exception ex)
{
Console.WriteLine("Main exception: " + ex);
}
finally
{
if(udpClient != null)
udpClient.Close();
if(tcpStream != null)
tcpStream.Close();
if(tcpClient != null)
tcpClient.Close();
}
Console.WriteLine("Press <ENTER> to exit.");
Console.ReadLine();
}
}
}
I have been making a C# server and client for a game. I have used many resources to try to create something successful. So far, the client can send stuff to the server and the server can receive them, but I want to be able to send stuff to the client. Also, I don't know what happened, but my server code suddenly stopped printing to console or something. I am new at this and any help is needed. I think I programmed both client and server to be able to send and receive, but something isn't right...
Note: I am using a cmd compiler running an old version of the .NET (but the code still compiles), any help on getting visual studio working to build/compile the code would also be nice :)
Client-side:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
class Program
{
static Boolean done = false;
static void Main(string[] args)
{
Boolean exception_thrown = false;
Socket sending_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
IPAddress send_to_address = IPAddress.Parse("ip-goes-here");
IPEndPoint sending_end_point = new IPEndPoint(send_to_address, 27020);
Console.WriteLine("Enter text to broadcast via UDP.");
Console.WriteLine("Enter a blank line to exit the program.");
Thread listenerT = new Thread(new ThreadStart(Program.listener));
listenerT.Start();
while (!done)
{
Console.WriteLine("Enter text to send, blank line to quit");
string text_to_send = Console.ReadLine();
if (text_to_send.Length == 0)
{
done = true;
listenerT.Abort();
}
else
{
byte[] send_buffer = Encoding.ASCII.GetBytes(text_to_send);
Console.WriteLine("sending to address: {0} port: {1}",
sending_end_point.Address,
sending_end_point.Port);
try
{
sending_socket.SendTo(send_buffer, sending_end_point);
}
catch (Exception send_exception)
{
exception_thrown = true;
Console.WriteLine(" Exception {0}", send_exception.Message);
}
if (exception_thrown == false)
{
Console.WriteLine("Message has been sent to the broadcast address");
}
else
{
exception_thrown = false;
Console.WriteLine("The exception indicates the message was not sent.");
}
}
}
}
static void listener()
{
int listenPort = 27020;
UdpClient listener = new UdpClient(listenPort);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);
string received_data;
byte[] receive_byte_array;
try
{
while (!done)
{
Console.WriteLine("Waiting for broadcast");
receive_byte_array = listener.Receive(ref groupEP);
Console.WriteLine("Received a broadcast from {0}", groupEP.ToString());
received_data = Encoding.ASCII.GetString(receive_byte_array, 0, receive_byte_array.Length);
Console.WriteLine("data follows \n{0}\n\n", received_data);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
Server side:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class UDPListener
{
private const int listenPort = 27020;
//static Boolean done = false;
static IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);
static UdpClient udpServer = new UdpClient(27020);
static IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 27020);
static byte[] data = udpServer.Receive(ref remoteEP); // listen on port 11000
static IPAddress send_to_address = IPAddress.Parse("10.240.0.1");
static IPEndPoint sending_end_point = new IPEndPoint(send_to_address, 27020);
public static void Main()
{
Console.WriteLine("Begin listening sequence");
while (true)
{
data = udpServer.Receive(ref groupEP);
Console.WriteLine("Received a broadcast from {0}", groupEP.ToString());
send_to_address = IPAddress.Parse(groupEP.ToString());
Thread listenerT = new Thread(new ThreadStart(UDPListener.sender));
listenerT.Start();
String received_data = Encoding.ASCII.GetString(data, 0, data.Length);
Console.WriteLine(received_data);
}
}
static void sender()
{
while (true)
{
Console.WriteLine("Enter text to send, blank line to quit");
string text_to_send = Console.ReadLine();
if (text_to_send.Length == 0)
{
//done = true;
}
else
{
byte[] send_buffer = Encoding.ASCII.GetBytes(text_to_send);
Console.WriteLine("sending to address: {0} port: {1}",
sending_end_point.Address,
sending_end_point.Port);
udpServer.Send(send_buffer, 0, remoteEP); // reply back
}
}
}
}
Nevermind, a friend of mine figured it out. You can find the final code in a github repo called something like flaming leaf server
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 am trying to program an ident sever to deal with the identity protocol requests from an irc server that I am programming an irc client for. The problem is I try to print to the screen the what I receive but nothing prints. I am not getting an error code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace ConnectIRC
{
class IdentityClass
{
private const int bufSize = 32;
public void IdentityRequest() {
TcpListener listener = null;
int port = 113;
IPEndPoint hostInfo = new IPEndPoint(IPAddress.Any, 113);
listener = new TcpListener(hostInfo);
listener.Start();
byte[] rcvBuffer = new byte[bufSize];
int rec;
for (; ; )
{
TcpClient client = null;
NetworkStream netStream = null;
client = listener.AcceptTcpClient();
if (listener.Pending())
{
Console.WriteLine("Connection was made");
}
netStream = client.GetStream();
//byte[] rcvBuffer = new byte[bufSize];
rec = netStream.Read(rcvBuffer, 0, rcvBuffer.Length);
Array.Resize(ref rcvBuffer, rec);
Console.WriteLine(Encoding.ASCII.GetString(rcvBuffer));
netStream.Close();
client.Close();
}
}
}
}
This is a very basic implementation of an ident server
Obviously it only accepts one connection and closes
Note you'll need to have a port mapped through your router for this to work
public class Ident
{
private readonly TcpListener _listener;
private readonly string _userId;
public Ident(string userId)
{
_userId = userId;
_listener = new TcpListener(IPAddress.Any, 113);
}
public void Start()
{
Console.WriteLine("Ident started");
_listener.Start();
var client = _listener.AcceptTcpClient();
_listener.Stop();
Console.WriteLine("Ident got a connection");
using (var s = client.GetStream())
{
var reader = new StreamReader(s);
var str = reader.ReadLine();
var writer = new StreamWriter(s);
Console.WriteLine("Ident got: " + str + ", sending reply");
writer.WriteLine(str + " : USERID : UNIX : " + _userId);
writer.Flush();
Console.WriteLine("Ident sent reply");
}
Console.WriteLine("Ident server exiting");
}
}