I'm working on a UDP Server-Client application.
When I create a new client, the client connect to the server and they begin to exchange data
This is my client constructor:
static EndPoint serverEP;
static Socket clientSocket;
public Client(Player client)
{
clientSocket = clientSocket = new Socket(
AddressFamily.InterNetwork,
SocketType.Dgram,
ProtocolType.Udp);
clientSocket.Bind(new IPEndPoint(IPAddress.Any,0));
clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
serverEP = new IPEndPoint(IPAddress.Parse(Server.serverIp), port);
}
After few actions I want to connect to another server.
My question is, is it possible to change port in the socket client?
I have tried this but it does not work, the program stay stuck:
public void changePort(int newPort)
{
clientSocket.Bind(new IPEndPoint(IPAddress.Any, 0));
serverEP = new IPEndPoint(IPAddress.Parse(Server.serverIp), newPort);
}
It is a solution to close a socket like this:
public void CloseSocket()
{
clientSocket.Shutdown(SocketShutdown.Send);
clientSocket.Close();
}
and start a new client on the new Port ?
Related
I am going to upgrade a system which used TCP connection without SSL. I want to add SSL encryption to the current connection without changing much in code. This is what there was previously in the code.
IPAddress ipAddress = IPAddress.Parse(IpAddress);
IPEndPoint remoteEP = new IPEndPoint(ipAddress, Port);
// Create a TCP/IP socket.
var client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
client.BeginConnect(remoteEP,new AsyncCallback(ConnectCallback), client);
What I tried is this,
IPAddress ipAddress = IPAddress.Parse(IpAddress);
IPEndPoint remoteEP = new IPEndPoint(ipAddress, Port);
// Create a TCP/IP socket.
var client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
while (!client.Connected) { }
NetworkStream stream = new NetworkStream(client);
SslStream ssl = new SslStream(stream, false, ValidateServerCertificate);
But this is not doing what I need. At least ValidateServerCertificate delegate is not called.
What's wrong with my code?
IMPORTANT
I cannot remove this socket named client during the change because it will affect lot of other codes.
So am trying to send a packet but am keep getting this error
Any help would be awesome!
Thanks a lot!
Error Message:
A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
Code:
private void button1_Click(object sender, EventArgs e)
{
byte[] packetData = Encoding.ASCII.GetBytes(textBox1.Text);
const string ip = "127.0.0.1";
const int port = 5588;
var ep = new IPEndPoint(IPAddress.Parse(ip), port);
var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.SendTo(packetData, ep);
}
}
}
var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
This creates a socket that will use TCP (which is a stream protocol). If you want to call Socket.SendTo on a connection oriented socket, you have to connect it first, through a call to Socket.Connect.
If you are intending to send datagrams only, it is a better choice to use UDP instead, which does not require connecting at all.
var client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
private void button1_Click(object sender, EventArgs e)
{
byte[] packetData = Encoding.ASCII.GetBytes(textBox1.Text);
const string ip = "75.126.77.26";
const int port = 5588;
var ep = new IPEndPoint(IPAddress.Parse(ip), port);
var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(ep);
client.SendTo(packetData, ep);
}
for clarity, added this line:
client.Connect(ep);
I think what you are looking for is calling client.Connect before calling client.SendTo. You'll also want to call client.Connected after you call connect to ensure you are connected.
This help page has an example of using the socket object: http://msdn.microsoft.com/en-us/library/2b86d684%28v=vs.110%29.aspx.
// Connect to the host using its IPEndPoint.
s.Connect(hostEndPoint);
if (!s.Connected)
{
// Connection failed, try next IPaddress.
strRetPage = "Unable to connect to host";
s = null;
continue;
}
I am new to socket programming in C#. Have searched the web like crazy for the solution to my problem but didnt find anything that could fix it. So heres my problem:
I am trying to write a client-server application. For the time being, the server will also run on my local machine. The application transmits a byte stream of data from the client to the server. The problem is that the server doesnt detect a client request for connection, while the client is able to connect and transmit the byte stream.
here is the server code:
String strHostName = Dns.GetHostName();
Console.WriteLine(strHostName);
IPAddress ip = IPAddress.Parse("127.0.0.1");
ipEnd = new IPEndPoint(ip, port);
soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
soc.Bind(ipEnd);
Console.WriteLine("Web Server Running... Press ^C to Stop...");
Thread th = new Thread(new ThreadStart(StartListen));
th.Start();
The StartListen thread is as below:
public void StartListen()
{
try
{
while (true)
{
string message;
Byte[] bSend = new Byte[1024];
soc.Listen(100);
if (soc.Connected)
{
Console.WriteLine("\nClient Connected!!\n==================\n CLient IP {0}\n", soc.RemoteEndPoint);
Byte[] bReceive = new Byte[1024 * 5000];
int i = soc.Receive(bReceive);
The client code is as follows:
hostIPAddress = IPAddress.Parse("127.0.0.1");
ipEnd = new IPEndPoint(hostIPAddress,port);
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
Console.WriteLine("Connecting to Server...");
clientSocket.Connect(ipEnd);
Console.WriteLine("Sending File...");
clientSocket.Send(clientData);
Console.WriteLine("Disconnecting...");
clientSocket.Close();
Console.WriteLine("File Transferred...");
Now what happens is that the server starts and when I run the client, it connects, sends and closes. But nothing happens on the server console, it doesnt detect any connection: if (soc.Connected) remains false.
I checked whether the server was listening to 127.0.0.1:5050 through netstat, and it sure was listening. Cant figure out the problem. Please help.
On the server side use Socket.Accept Method to accept incoming connection. The method returns a Socket for a newly created connection: the Send() and Receive() methods can be used for this socket.
For example, after accepting the separate thread can be created to process the client connection (i.e. client session).
private void ClientSession(Socket clientSocket)
{
// Handle client session:
// Send/Receive the data.
}
public void Listen()
{
Socket serverSocket = ...;
while (true)
{
Console.WriteLine("Waiting for a connection...");
var clientSocket = serverSocket.Accept();
Console.WriteLine("Client has been accepted!");
var thread = new Thread(() => ClientSession(clientSocket))
{
IsBackground = true
};
thread.Start();
}
}
The following code sends a packet on port 15000:
int port = 15000;
UdpClient udp = new UdpClient();
//udp.EnableBroadcast = true; //This was suggested in a now deleted answer
IPEndPoint groupEP = new IPEndPoint(IPAddress.Broadcast, port);
string str4 = "I want to receive this!";
byte[] sendBytes4 = Encoding.ASCII.GetBytes(str4);
udp.Send(sendBytes4, sendBytes4.Length, groupEP);
udp.Close();
However, it's kind of useless if I can't then receive it on another computer. All I need is to send a command to another computer on the LAN, and for it to receive it and do something.
Without using a Pcap library, is there any way I can accomplish this? The computer my program is communicating with is Windows XP 32-bit, and the sending computer is Windows 7 64-bit, if it makes a difference. I've looked into various net send commands, but I can't figure them out.
I also have access to the computer (the XP one)'s local IP, by being able to physically type 'ipconfig' on it.
EDIT: Here's the Receive function I'm using, copied from somewhere:
public void ReceiveBroadcast(int port)
{
Debug.WriteLine("Trying to receive...");
UdpClient client = null;
try
{
client = new UdpClient(port);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
IPEndPoint server = new IPEndPoint(IPAddress.Broadcast, port);
byte[] packet = client.Receive(ref server);
Debug.WriteLine(Encoding.ASCII.GetString(packet));
}
I'm calling ReceiveBroadcast(15000) but there's no output at all.
Here is the simple version of Server and Client to send/receive UDP packets
Server
IPEndPoint ServerEndPoint= new IPEndPoint(IPAddress.Any,9050);
Socket WinSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
WinSocket.Bind(ServerEndPoint);
Console.Write("Waiting for client");
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0)
EndPoint Remote = (EndPoint)(sender);
int recv = WinSocket.ReceiveFrom(data, ref Remote);
Console.WriteLine("Message received from {0}:", Remote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
Client
IPEndPoint RemoteEndPoint= new IPEndPoint(
IPAddress.Parse("ServerHostName"), 9050);
Socket server = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
string welcome = "Hello, are you there?";
data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint);
After a long break, i tried to refresh my memory of System.Net.Sockets but i am encountering problems with just connect even 2 machines.
Exception: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
Server Code:
private void startButton_Click(object sender, EventArgs e)
{
LocalEndpoint = new IPEndPoint(IPAddress.Parse("192.168.1.103"), 4444);
_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_Socket.Bind(LocalEndpoint);
_Socket.Listen(10);
_Socket.BeginAccept(new AsyncCallback(Accept), _Socket);
}
private void Accept(IAsyncResult _IAsyncResult)
{
Socket AsyncSocket = (Socket)_IAsyncResult.AsyncState;
AsyncSocket.EndAccept(_IAsyncResult);
buffer = new byte[1024];
AsyncSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(Receive), AsyncSocket);
}
private void Receive(IAsyncResult _IAsyncResult)
{
Socket AsyncSocket = (Socket)_IAsyncResult.AsyncState;
AsyncSocket.EndReceive(_IAsyncResult);
strReceive = Encoding.ASCII.GetString(buffer);
Update_Textbox(strReceive);
buffer = new byte[1024];
AsyncSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(Receive), AsyncSocket);
}
Client Code:
private void connectButton_Click(object sender, EventArgs e)
{
RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.103"), 4444);
_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_Socket.BeginConnect(RemoteEndPoint, new AsyncCallback(Connect), _Socket);
}
private void Connect(IAsyncResult _IAsyncResult)
{
Socket RemoteSocket = (Socket)_IAsyncResult.AsyncState;
RemoteSocket.EndConnect(_IAsyncResult);
}
The error is due to following line in your Accept function:
AsyncSocket.EndAccept(_IAsyncResult);
Server listens to a particular socket and it uses it to accept connections from the client. You can not use same socket to accept connections and receive data from the client. If you look at the help of Socket.EndAccept it says that it creates a new Socket to handle remote host communication. In your code you are using _Socket to listen for client connections and to receive data. You can modify this line to:
Socket dataSocket = AsyncSocket.EndAccept(_IAsyncResult);
You also need to pass this new socket to BeginReceive function parameter as:
AsyncSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(Receive), dataSocket);