Listen socket listens only once - c#

I have a problem with my server socket code below - the loop in the Main() method is only executing once, never accepting any further input.
class Server
{
public Socket servSock(int Port)
{
Socket s1 = null;
IPHostEntry ipHE = Dns.GetHostEntry("localhost");
IPAddress ipA = ipHE.AddressList[0];
IPEndPoint ipEp = new IPEndPoint(ipA, Port);
s1 = new Socket(ipEp.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
s1.Bind(ipEp);
return s1;
}
const int BUFFSIZE = 1024;
const int BACKLOG = 255;
static void Main(string[] args)
{
Nwork nwork = new Nwork();
Socket cl = null;
Socket s = nwork.servSock(400);
s.Listen(BACKLOG);
byte[] rcvBuffer = new byte[BUFFSIZE];
for (; ; )
{
string text = "";
Console.Clear();
cl = s.Accept();
Console.Write("Handling Client >> " + cl.RemoteEndPoint +"\n\n\n");
cl.Receive(rcvBuffer, BUFFSIZE, SocketFlags.None);
text = Encoding.ASCII.GetString(rcvBuffer, 0, BUFFSIZE).TrimEnd('\0');
Console.Write(text);
cl.Close();
}
}
}

I don't know what an "Nwork" is, but I suspect that's the source of your bug. Just initializing the socket manually works for me and allows subsequent connections.
static void Main(string[] args)
{
Socket s = new Socket(SocketType.Stream, ProtocolType.TCP);
Socket cl = null;
System.Net.IPEndPoint endpoint = new System.Net.IPEndPoint(0, 400); // listen on all adapters on port 400
s.Bind(endpoint);
s.Listen(BACKLOG);
byte[] rcvBuffer = new byte[BUFFSIZE];
for (; ; )
{
string text = "";
Console.Clear();
cl = s.Accept();
Console.Write("Handling Client >> " + cl.RemoteEndPoint + "\n\n\n");
cl.Receive(rcvBuffer, BUFFSIZE, SocketFlags.None);
text = Encoding.ASCII.GetString(rcvBuffer, 0, BUFFSIZE).TrimEnd('\0');
Console.Write(text);
cl.Close();
}
}

Without deep diving in your code i would try adding the s.Listen(BACKLOG) in your for loop.
Note that this way you can only process i socket connection at the same time, if another person is gonna try and open a socket connection your process will be busy receiving the data from a previous connection.
It depends on your scenario but you might want to implement it asynchronous.
This link might be usefull if you decided to do so.

Related

c# test bandwidth between server and client applications

I am new to programming. For my first application I decided to create two console applications - server and client application. I want to test data transaction bandwith between client and server app(by the way I am using sockets). The problem I have is that I need to test connection speed for, lets say 10 seconds and after those 10 seconds I need to get received data amount (which I have received in this time period) and calculate speed...How can I do that?
Client app
namespace Example_01_Sockets_Client
{
class MainClass
{
public static void Main(string[] args)
{
try
{
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var ownAddress = IPAddress.Parse("127.0.0.1");
var ownEndpoint = new IPEndPoint(ownAddress, 4321);
socket.Bind(ownEndpoint);
Console.WriteLine();
Console.WriteLine("Trying to connect to server...");
var serverAddress = IPAddress.Parse("127.0.0.1");
socket.Connect(serverAddress, 2222);
Console.WriteLine("Connected to server");
var buffer = new byte[1024 * 150000];
socket.ReceiveTimeout = 100;
int receivedBytesLen = socket.Receive(buffer);
Console.WriteLine("Download speed: " + ((receivedBytesLen) / 100 + "kb/s ") );
Console.WriteLine("Press any key to exit");
Console.ReadKey();
socket.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
Server App
class MainClass
{
public static void Main(string[] args)
{
bool exit = false;
while (!exit)
{
var listeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint localEndpoint = new IPEndPoint(ipAddress, 2222);
listeningSocket.Bind(localEndpoint);
listeningSocket.Listen(1);
Console.WriteLine();
Console.WriteLine("Waiting for client...");
Socket connectedSocket = listeningSocket.Accept();
listeningSocket.Close();
string clientAddress = connectedSocket.RemoteEndPoint.ToString();
Console.WriteLine("Client connected (" + clientAddress + ")");
string fileName = "downTest.txt";
byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName);
byte[] fileData = File.ReadAllBytes(fileName);
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + fileNameByte.Length);
connectedSocket.Send(fileData);
//int bytesReceived = connectedSocket.Receive();
Console.WriteLine("Client connected (" + clientAddress + ")");
connectedSocket.Close();
}
}
}
Thanks for any help!!!
Why not use a set amount of data (eg. 4,096kb). Use the Stopwatch class to start a timer right before you start downloading data on the client, and then stop the timer immediately after it finishes sending. You can then use the elapsed time property to determine how long it took to send that fixed amount of data.
Stopwatch timer = new Stopwatch();
timer.Start();
// Download data here
timer.Stop();
int elapsedTime = timer.Elapsed.TotalSeconds;

Cannot access a disposed object. in c# client & Server

I had fix my Problem Cannot access a disposed object. in c# client & Server
Following Points I Used.
Used Using for Scope Limitation
i am not Closed Socket Object
class Client
{
static void Main(string[] args)
{
Console.Title = "Client Chat";
byte[] bytes = new byte[1024];// data buffer for incoming data
string data = null;
// connect to a Remote device
try
{
// Establish the remote end point for the socket
IPHostEntry ipHost = Dns.Resolve("localhost");
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 95);
using (Socket Socketsender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
Socketsender.Connect(ipEndPoint);
Console.WriteLine("\n\n\tSocket Connecting To Java Server...." + Socketsender.RemoteEndPoint.ToString());
while (true)
{
Console.Write("\n\n\tClient::");
string theMessage = Console.ReadLine();
byte[] msg = Encoding.ASCII.GetBytes(theMessage);
// Send the data through the socket
int bytesSent = Socketsender.Send(msg);
//Recieved from Java Server Message
int bytesRec = Socketsender.Receive(bytes);
Console.WriteLine("\n\n\tJava Server Says:: {0}", Encoding.ASCII.GetString(bytes, 0, bytesRec));
}
//Socketsender.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadLine();
}
}
You create your Socket handler object outside the loop and close it inside the loop. The second pass through your loop you are looking at a Socket object that you have already closed.
Don't close your Socket until you are finished with it.

c# being done with a remote computer sending and receiving data using stunserver

I can not send data stunserver remote computer using the two. Data comes from local computers, but data on remote computers is not going to come.
I'm using my program, stunserver
public void run()
{
UpdateText("Now Listening..");
remoteSender = new IPEndPoint(IPAddress.Any, 0);
tempRemoteEP = (EndPoint)remoteSender;
byte[] packet = new byte[1024];
while (true)
{
if (socket.Available > 0)
{
this.nbBytesRx = socket.ReceiveFrom(packet, ref tempRemoteEP);
nbPackets++;
seqNo = BitConverter.ToInt16(packet, 0);
UpdateText(nbPackets.ToString() + ":" + seqNo.ToString() + " / ");
}
}
}
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(new IPEndPoint(IPAddress.Any, 0));
string localEP = socket.LocalEndPoint.ToString();
string publicEP = "";
string netType = "";
STUN_Result result = STUN_Client.Query("stunserver.org", 3478, socket);
netType = result.NetType.ToString();
if (result.NetType != STUN_NetType.UdpBlocked)
{
publicEP = result.PublicEndPoint.ToString();
}
else
{
publicEP = "";
}
UpdateText("Local EP:" + localEP);
UpdateText("Public EP:" + publicEP);
ThreadStart startMethod = new ThreadStart(this.run);
thread = new Thread(startMethod);
thread.Start();
I am working on the same problem, and using the same library.
Did you check if you get your endpoint? I found our that pointed server wasn`t online. So I made a List of servers to go throught.
My method to get public EP:
public static IPEndPoint GetMyPublicEP() {
// Create new socket for STUN client.
Socket _socket = new Socket
(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_socket.Bind(new IPEndPoint(IPAddress.Any, 0));
List<string> _stunServers = new List<string> { // список стан серверов для проверки своей ендпоинт, не все работают
"stun.l.google.com:19302",
"stun1.l.google.com:19302",
"stun2.l.google.com:19302",
"stun3.l.google.com:19302",
"stun4.l.google.com:19302",
"stun01.sipphone.com",
"stun.ekiga.net",
"stun.fwdnet.net",
"stun.ideasip.com",
"stun.iptel.org",
"stun.rixtelecom.se",
"stun.schlund.de",
"stunserver.org",
"stun.softjoys.com",
"stun.voiparound.com",
"stun.voipbuster.com",
"stun.voipstunt.com",
"stun.voxgratia.org",
"stun.xten.com"
};
foreach (string server in _stunServers)
{
try
{
STUN_Result result = STUN_Client.Query(server, 3478, _socket);
IPEndPoint myPublicEPStun = result.PublicEndPoint;
if (myPublicEPStun != null)
{
_myPublicEPStun = myPublicEPStun;
break;
}
}
catch (Exception E)
{
Console.WriteLine("Якась необ`ясніма магія трапилась");
}
}
return _myPublicEPStun;
}
I had the same problem... i solved it disabling Windows Firewall. It was blocking all the traffic.

C# TCP Chat Application Threading

I am in desperate need of help. I have essentially created a program that (will use) encryption to send messages back and forth. The encryption part is working fine, however I am fairly new to Threads and I can not for the life of me get my Client/Server pieces of the application to line up. The chat program is direct IP connection using TCP, so each host is a client and a server. The issue I appear to be having, when I debug, is that the server thread is either not ready when the Client tries to connect to it, or if it is ready it will not relinquish the Thread so the Client can connect! I have been working on this for hours and it is very frustrating.. I hope someone can help! I've included my code below.
This is my code snippet from my MainForm, which constructs the Client and Server aspects:
private void InitializeComponent() {
server = new ServerSide("127.0.0.1",7865);
servThread = new Thread(new ThreadStart(server.begin));
client = new ClientSide("127.0.0.1",7865);
clientThread = new Thread(new ThreadStart(client.begin));
servThread.Start();
clientThread.Start();
//servThread.Join();
//clientThread.Join();
}
This is my ServerSide code:
public class ServerSide
{
String IpString;
int tcpPort;
bool goodToGo = false;
System.Net.IPAddress ipAddress = null;
public ServerSide(String ip, int tcpPort)
{
IpString = ip;
bool isValidIp = System.Net.IPAddress.TryParse(IpString, out ipAddress);
if (isValidIp == true) // check if the IP is valid, set the bool to true if so
{
goodToGo = true;
}
else
{
goodToGo = false;
}
}
public void begin()
{
try
{
IPAddress ipAd = IPAddress.Parse(IpString);
/* Initializes the Listener */
TcpListener myList = new TcpListener(ipAd, tcpPort);
Socket s = null;
/* Start Listening at the specified port */
while (true)
{
myList.Start();
if (myList.Pending())
{
s = myList.AcceptSocket();
break;
}
}
String toReceive = "";
while (true)
{
byte[] b = new byte[4096];
int k = s.Receive(b);
for (int i = 0; i < k; i++)
toReceive += Convert.ToString((Convert.ToChar(b[i])));
// ASCIIEncoding asen = new ASCIIEncoding();
var form = MainForm.ActiveForm as MainForm;
if (form != null)
{
form.messageReceived(toReceive);
}
toReceive = "";
}
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
}
}
}
}
ClientSide code:
public class ClientSide
{
private String IpString;
private int tcpPort;
private TcpClient tcpInt;
private static Stream stm;
private System.Net.IPAddress ipAddress = null;
private bool goodToGo = false;
public ClientSide(String ip, int tcpPort)
{
IpString = ip;
this.tcpPort = tcpPort;
bool isValidIp = System.Net.IPAddress.TryParse(IpString, out ipAddress);
if (isValidIp == true)
{
goodToGo = true;
}
else
{
goodToGo = false;
}
}
public void begin()
{
try
{
tcpInt = new TcpClient();
// Console.WriteLine("Connecting.....");
tcpInt.Connect(IpString, tcpPort);
// use the ipaddress as in the server program
// Console.WriteLine("Connected");
// String str = Console.ReadLine();
stm = tcpInt.GetStream();
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
}
}
public void sendMessage(String str)
{
// stm = tcpInt.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes(str);
stm.Write(ba, 0, ba.Length);
/** 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]));*/
}
}
}
Once again.. what typically happens is my Client receives an error that the host actively refused the connection.. but I do not know how to time them. I am looking for how to have my server listening for TCP Connections, but still manage to go to my other thread to create the TCP Connecion to send the server (I am testing this on localhost currently).
Thanks.
In the constructor of the ServerSide class, you forgot to initialize the tcpPort member. Because you forgot, the server will try to listen to port 0 and the client will try to connect to port 7865, and it will fail.
Try adding this code to the constructor in the ServerSide class.
this.tcpPort = tcpPort;
As for the threads, you might have a problem if the client thread tries to connect before the server thread has started listening. You can use a loop to try to connect a number of times (let's say 10), with a timeout (let's say 1 second) if you don't succeed. This way, you will retry 10 times and give up after that.

TCP/UDP Socket server on WAN

I have written a socket server in c# that will be used as the basic design for a small game project I am part of. The socket server works fine on lan. I able to communicate completely fine between the server and the client. However on the WAN the server receives all the correct messages from the client, but the client receives no messages from the server. Both the client and the server are behind a router but only the server's router has the ports forwarded. When the client connects to the server I get the IP address of the connection. Because the client is behind a NAT, is there more information from the sender that I need to collect? I assume the client could set up port forwarding but that would be VERY counter-productive to the game. Any help I can get is appreciated. If you need code let me know. Thanks in advance.
Used to make the TCP connection from the client
public string ConnectionAttempt(string ServeIP, string PlayUsername)
{
username = PlayUsername;
try
{
connectionClient = new TcpClient(ServeIP,TCP_PORT_NUMBER);
connectionClient.GetStream().BeginRead(readbuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(DoRead), null);
Login(username);
ipAddress = IPAddress.Parse(((IPEndPoint)connectionClient.Client.RemoteEndPoint).Address.ToString());
servIP = new IPEndPoint(ipAddress,65002);
listenUDP = new IPEndPoint(ipAddress, 0);
UDPListenerThread = new Thread(receiveUDP);
UDPListenerThread.IsBackground = true;
UDPListenerThread.Start();
return "Connection Succeeded";
}
catch(Exception ex) {
return (ex.Message.ToString() + "Connection Failed");
}
}
Listens for a UDP message on a thread.
private void receiveUDP()
{
System.Net.IPEndPoint test = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0);
System.Net.EndPoint serverIP = (System.Net.EndPoint)test;
server.Bind(serverIP);
EndPoint RemoteServ = (EndPoint)servIP;
while (true)
{
byte[] content = new byte[1024];
int data = server.ReceiveFrom(content, ref RemoteServ);
string message = Encoding.ASCII.GetString(content);
result = message;
ProcessCommands(message);
}
}
Server TCP connection Listener:
private void ConnectionListen()
{
try
{
listener = new TcpListener(System.Net.IPAddress.Any, PORT_NUM);
listener.Start();
do
{
UserConnection client = new UserConnection(listener.AcceptTcpClient());
client.LineRecieved += new LineRecieve(OnLineRecieved);
UpdateStatus("Someone is attempting a login");
} while (true);
}
catch
{
}
}
Server UDP Listener:
private void receiveUDP()
{
System.Net.IPEndPoint test = new System.Net.IPEndPoint(System.Net.IPAddress.Any, UDP_PORT);
System.Net.EndPoint serverIP = (System.Net.EndPoint)test;
trans.Bind(serverIP);
System.Net.IPEndPoint ipep = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0);
System.Net.EndPoint Remote = (System.Net.EndPoint)ipep;
while (true)
{
byte[] content = new byte[1024];
int recv = trans.ReceiveFrom(content,ref Remote);
string message = Encoding.ASCII.GetString(content);
string[] data = message.Split((char)124);
//UpdateStatus(data[0] + data[1]);
UserConnection sender = (UserConnection)clients[data[0]];
sender.RemoteAdd = Remote;
if (data.Length > 2)
{
OnLineRecieved(sender, data[1] + "|" + data[2]);
}
else
{
OnLineRecieved(sender, data[1]);
}
}
}
Setup Information for a user connection Server-side:
Socket trans = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp); //UDP connection for data transmission in game.
public PlayerLoc Location = new PlayerLoc();
public UserConnection(TcpClient client)//TCP connection established first in the Constructor
{
this.client = client;
ipAdd = IPAddress.Parse(((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString());
ipep = new IPEndPoint(ipAdd, ((IPEndPoint)client.Client.RemoteEndPoint).Port);
this.client.GetStream().BeginRead(readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(StreamReciever), null);
}
Method for sending data to individual users:
public void SendData(string data)//UDP only used during transmission
{
byte[] dataArr = Encoding.ASCII.GetBytes(data);
trans.SendTo(dataArr, dataArr.Length,SocketFlags.None, RemoteAdd);
}
The client must start the UDP communication so that it can get a "hole" in the router/firewall. And the UDP server must reply back using the end point referenced in ReceviedFrom

Categories

Resources