Right now, when i press the connect button i will be connected to the server by the default ip address and port number. clientSocket.Connect("127.0.0.1", 8888);
I would like to create 2 textbox in the GUI , 1 for the IP address and 1 for port.
So that user can manually key in the IP add and port.
May i know how to do this. thanks.
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.Net.Sockets;
using System.Threading;
namespace SocketClient
{
public partial class SocketClient : Form
{
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
NetworkStream serverStream = default(NetworkStream);
string readData = null;
public SocketClient()
{
InitializeComponent();
}
private void getMessage()
{
while (true)
{
serverStream = clientSocket.GetStream();
int buffSize = 0;
byte[] inStream = new byte[10025];
buffSize = clientSocket.ReceiveBufferSize;
serverStream.Read(inStream, 0, buffSize);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
readData = "" + returndata;
msg();
}
}
private void msg()
{
if (this.InvokeRequired)
this.Invoke(new MethodInvoker(msg));
else
textDisplay.Text = textDisplay.Text + Environment.NewLine + " >> " + readData;
}
private void buttonConnect_Click(object sender, EventArgs e)
{
readData = "Conected to NYP Chat Server ...";
msg();
//
clientSocket.Connect("127.0.0.1", 8888);
serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textName.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
Thread ctThread = new Thread(getMessage);
ctThread.Start();
}
private void buttonSend_Click(object sender, EventArgs e)
{
}
private void textDisplay_TextChanged(object sender, EventArgs e)
{
}
}
}
In the designer view, add two TextBoxes in the desired positions and name the texbboxes as tbIp and tbPort.
update the line following line
clientSocket.Connect("127.0.0.1", 8888);
to
clientSocket.Connect(tbIp.Text, Convert.Int32(tbPort.Text));
Regards
ArunDhaJ
Related
I am trying to make a Server app and client app to connect through internet using C#.
Here is my Server app...
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 Server
{
public partial class Form1 : Form
{
private byte[] data = new byte[1024];
private int size = 1024;
private Socket server;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.ControlBox = false;
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
}
private void button2_Click(object sender, EventArgs e)
{
server = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(System.Net.IPAddress.Any, 8001);
server.Bind(iep);
server.Listen(1);
server.BeginAccept(new AsyncCallback(AcceptConn), server);
textBox1.Text = "Server Started!! \r\nWaiting for client...";
}
void AcceptConn(IAsyncResult iar)
{
Socket oldserver = (Socket)iar.AsyncState;
Socket client = oldserver.EndAccept(iar);
textBox1.Text = "Connected to: " + client.RemoteEndPoint.ToString();
string stringData = "Welcome to my server";
byte[] message1 = Encoding.ASCII.GetBytes(stringData);
client.BeginSend(message1, 0, message1.Length, SocketFlags.None,
new AsyncCallback(SendData), client);
}
void SendData(IAsyncResult iar)
{
Socket client = (Socket)iar.AsyncState;
int sent = client.EndSend(iar);
client.BeginReceive(data, 0, size, SocketFlags.None,
new AsyncCallback(ReceiveData), client);
}
void ReceiveData(IAsyncResult iar)
{
Socket client = (Socket)iar.AsyncState;
int recv = client.EndReceive(iar);
if (recv == 0)
{
client.Close();
textBox1.Text = "Waiting for client...";
server.BeginAccept(new AsyncCallback(AcceptConn), server);
return;
}
string receivedData = Encoding.ASCII.GetString(data, 0, recv);
listBox1.Items.Add(receivedData);
byte[] message2 = Encoding.ASCII.GetBytes(receivedData);
client.BeginSend(message2, 0, message2.Length, SocketFlags.None,
new AsyncCallback(SendData), client);
}
private void label1_Click(object sender, EventArgs e)
{
}
private void button3_Click(object sender, EventArgs e)
{
server.Close();
//server.Shutdown();
}
void ButtonStopOnClick(object obj, EventArgs ea)
{
Close();
}
}
}
And here is my Client app...
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
{
private TextBox newText;
private TextBox conStatus;
private ListBox results;
private Socket client;
private byte[] data = new byte[1024];
private int size = 1024;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.ControlBox = false;
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
}
private void button2_Click(object sender, EventArgs e)
{
textBox2.Text = "Connecting...";
Socket newsock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("192.168.0.3"), 8001);
//IPEndPoint iep = new IPEndPoint(IPAddress.Parse("41.232.217.55"), 8001);
newsock.BeginConnect(iep, new AsyncCallback(Connected), newsock);
}
private void button3_Click(object sender, EventArgs e)
{
byte[] message = Encoding.ASCII.GetBytes(textBox1.Text);
textBox1.Clear();
client.BeginSend(message, 0, message.Length, SocketFlags.None,
new AsyncCallback(SendData), client);
}
private void button4_Click(object sender, EventArgs e)
{
client.Close();
textBox2.Text = "Disconnected";
}
void Connected(IAsyncResult iar)
{
client = (Socket)iar.AsyncState;
try
{
client.EndConnect(iar);
textBox2.Text = "Connected to: " + client.RemoteEndPoint.ToString();
client.BeginReceive(data, 0, size, SocketFlags.None,
new AsyncCallback(ReceiveData), client);
}
catch (SocketException)
{
textBox2.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);
listBox1.Items.Add(stringData);
}
void SendData(IAsyncResult iar)
{
Socket remote = (Socket)iar.AsyncState;
int sent = remote.EndSend(iar);
remote.BeginReceive(data, 0, size, SocketFlags.None,
new AsyncCallback(ReceiveData), remote);
}
}
}
I understand that the server app can use IPaddress.Any but the client must be specific to reach the server.
My problem is that i cant connect form another computer outside the local addressing (192.168.0.1, 192.168.0.2,....). I want the client to be able to connect to my server using my remote IP (41.232.217.55).
I searched a lot but all examples in the internet are console application. I've tried use console application example for windows forms but when I call socket.start form freezes and status changes to (not response). Also I tried multiple threads but it's unsuccessful too. If it is possible please advice me something.
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.Net;
using System.Net.Sockets;
using System.Threading;
namespace mserver1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ServerClass sc = new ServerClass();
sc.startServer(textBox1, richTextBox1);
}
}
public class ServerClass
{
public void startServer(TextBox tb, RichTextBox rb)
{
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9939);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(ip);
socket.Listen(20);
rb.Text = rb.Text + "Waiting for client...";
Socket client = socket.Accept();
IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;
rb.Text = rb.Text + "Connected with " + clientep.Address + " at port " + clientep.Port;
string welcome = tb.Text;
byte[] data = new byte[1024];
data = Encoding.ASCII.GetBytes(welcome);
client.Send(data, data.Length, SocketFlags.None);
rb.Text = rb.Text + "Disconnected from" + clientep.Address;
client.Close();
socket.Close();
}
}
}
Thanks.
Your application will block until button1_Click returns.
You need to spawn a worker thread to do your listening. Additionally, you should not pass your controls directly into the worker thread. Rather, you should have a callback that will populate your controls with the data that comes from the socket communications.
Look up information on the BackgroundWorker. This will get you where you need to go.
I had the same problem, follow my solution for the SERVER
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;
using System.Threading;
namespace SERVER_WIN
{
public partial class Form1 : Form
{
//Declare and Initialize the IP Adress
static IPAddress ipAd = IPAddress.Parse("10.1.42.31");
//Declare and Initilize the Port Number;
static int PortNumber = 8888;
/* Initializes the Listener */
TcpListener ServerListener = new TcpListener(ipAd, PortNumber);
TcpClient clientSocket = default(TcpClient);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Thread ThreadingServer = new Thread(StartServer);
ThreadingServer.Start();
}
private void THREAD_MOD(string teste)
{
txtStatus.Text += Environment.NewLine + teste;
}
private void StartServer()
{
Action<string> DelegateTeste_ModifyText = THREAD_MOD;
ServerListener.Start();
Invoke(DelegateTeste_ModifyText, "Server waiting connections!");
clientSocket = ServerListener.AcceptTcpClient();
Invoke(DelegateTeste_ModifyText, "Server ready!");
while (true)
{
try
{
NetworkStream networkStream = clientSocket.GetStream();
byte[] bytesFrom = new byte[20];
networkStream.Read(bytesFrom, 0, 20);
string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
string serverResponse = "Received!";
Byte[] sendBytes = Encoding.ASCII.GetBytes(serverResponse);
networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();
}
catch
{
ServerListener.Stop();
ServerListener.Start();
Invoke(DelegateTeste_ModifyText, "Server waiting connections!");
clientSocket = ServerListener.AcceptTcpClient();
Invoke(DelegateTeste_ModifyText, "Server ready!");
}
}
}
}
}
You will need to put in your windows forms just one control TextView, named txtStatus.
Client Program:
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;
using System.IO;
namespace CLIENT_WIN
{
public partial class Form1 : Form
{
TcpClient tcpclnt = new TcpClient();
//Declare and Initialize the IP Adress
IPAddress ipAd = IPAddress.Parse("10.1.42.31");
//Declare and Initilize the Port Number;
int PortNumber = 8888;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Console.WriteLine("Connecting.....");
try
{
tcpclnt.Connect(ipAd, PortNumber);
txtStatus.Text += Environment.NewLine + "Connected";
txtStatus.Text += Environment.NewLine + "Enter the string to be transmitted";
}
catch { }
}
private void btnEnviar_Click(object sender, EventArgs e)
{
String str = txtEnviar.Text + "$";
Stream stm = tcpclnt.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes(str);
txtStatus.Text += Environment.NewLine + "Transmitting...";
//Console.WriteLine("Transmitting.....");
stm.Write(ba, 0, ba.Length);
byte[] bb = new byte[100];
int k = stm.Read(bb, 0, 100);
string Response = Encoding.ASCII.GetString(bb);
txtStatus.Text += Environment.NewLine + "Response from server: " + Response;
}
}
}
For the Client you will need put some controls;
two TextViews (txtStatus and txtEnviar) and a button named btnEnviar, that is it!
You must run at first the Server, than you can run the client, if you need to stop the client, dont worry you can let the Server running.
Hello I am doing a socket program in C# and now I have got a problem. I use this server program code and this client code that I have been finding. I have ben modifying it some. So the problem I haw is that I do want to be able to disconnect from the server, I have been trying and googling it a lot but can't find out how to do it. What is the easy way to do it with this code??
the client code
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.Net.Sockets;
namespace soket_client_delen
{
public partial class Form1 : Form
{
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
public Form1()
{
InitializeComponent();
this.textBox2.KeyPress += new System.Windows.Forms.KeyPressEventHandler(CheckKeys);
}
private void CheckKeys(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if (e.KeyChar == (char)13)
{
// Then Enter key was pressed
if (checkBox1.Checked ==true)
send();
}
}
private void Form1_Load(object sender, EventArgs e)
{
msg("Client Started");
clientSocket.Connect("127.0.0.1", 8888);
label1.Text = "Client Socket Program - Server Connected ...";
}
private void button1_Click_1(object sender, EventArgs e)
{
send();
}
public void send()
{
NetworkStream serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textBox2.Text +"$");
textBox2.Text = "";
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
byte[] inStream = new byte[10025];
serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
msg("Data from Server : " + returndata);
}
public void msg(string mesg)
{
textBox1.Text = textBox1.Text + Environment.NewLine + " >> " + mesg;
}
private void button2_Click(object sender, EventArgs e)
{
}
}
}
and server code:
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace soket_serverdelen
{
class Program
{
static void Main(string[] args)
{
TcpListener serverSocket = new TcpListener(8888);
TcpClient clientSocket = default(TcpClient);
int counter = 0;
serverSocket.Start();
Console.WriteLine(" >> " + "Server Started");
counter = 0;
while (true)
{
counter += 1;
clientSocket = serverSocket.AcceptTcpClient();
Console.WriteLine(" >> " + "Client No:" + Convert.ToString(counter) + " started!");
handleClinet client = new handleClinet();
client.startClient(clientSocket, Convert.ToString(counter));
}
clientSocket.Close();
serverSocket.Stop();
Console.WriteLine(" >> " + "exit");
Console.ReadLine();
}
}
//Class to handle each client request separatly
public class handleClinet
{
TcpClient clientSocket;
string clNo;
public void startClient(TcpClient inClientSocket, string clineNo)
{
this.clientSocket = inClientSocket;
this.clNo = clineNo;
Thread ctThread = new Thread(doChat);
ctThread.Start();
}
private void doChat()
{
int requestCount = 0;
byte[] bytesFrom = new byte[10025];
string dataFromClient = null;
Byte[] sendBytes = null;
string serverResponse = null;
string rCount = null;
requestCount = 0;
while ((true))
{
try
{
requestCount = requestCount + 1;
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
rCount = Convert.ToString(requestCount);
serverResponse = "Server to clinet(" + clNo + ") " + rCount;
sendBytes = Encoding.ASCII.GetBytes(serverResponse);
networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();
Console.WriteLine(" >> " + serverResponse);
}
catch (Exception ex)
{
Console.WriteLine(" >> " + ex.ToString());
}
}
}
}
}
Thanks you for all help
Did you try clientSocket.Close()?
http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.close.aspx
You need to have both sides calling close. Typically, though not a hard and fast rule, the client terminates the connection and the server side responds to that. So, when your client is done transmitting/receiving, the client side calls close. The server side then responds to that and calls close on its side.
For client side:
NetworkStream ns = clientSocket.GetStream();
// send important stuff
// receive important stuff from server
ns.Close();
For the server side:
NetworkStream ns = clientSocket.GetStream();
int bytesRead;
while((bytesRead = ns.Read(buffer, 0, buffer.Length)) >= 0) {
if(bytesRead > 0) {
// do really important stuff
} else if(bytesRead == 0) {
// client has trasmitted FIN packet, close and exit thread
ns.Close();
} else {
// handle error condition
// probably close the connection
}
}
The above code is a model only. I've not tested it. You're using network streams so this example (I think) should be helpful. I usually use select() (from the windows API, .NET exposes it in the Socket class) for doing this. Basically, when either side closes the connection, via Close(), the Windows TCP stacks send a TCP FIN packet. This signals that the originating side wishes to close the connection. Also, someone commented that you should wrap your use of these streams in a using clause. That's imperative if you're not going to call Close() directly.
Typically the client would send a logoff-signal to the server. Upon receiving this message the server closes the connection. The client should run a loop untill serverStream.Socket.Closed = True before exiting.
how to add in exception showing the input has to be enter, if the user click on connect without entering any input? i would like the have a message box show if the user click on the connect button without entering the name, ip and port. [SOLVED]
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.Net.Sockets;
using System.Threading;
namespace SocketClient
{
public partial class SocketClient : Form
{
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
NetworkStream serverStream = default(NetworkStream);
string readData = null;
public SocketClient()
{
InitializeComponent();
}
private void getMessage()
{
while (true)
{
serverStream = clientSocket.GetStream();
int buffSize = 0;
byte[] inStream = new byte[10025];
buffSize = clientSocket.ReceiveBufferSize;
serverStream.Read(inStream, 0, buffSize);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
readData = "" + returndata;
msg();
}
}
private void msg()
{
if (this.InvokeRequired)
this.Invoke(new MethodInvoker(msg));
else
textDisplay.Text = textDisplay.Text + Environment.NewLine + " >> " + readData;
}
private void buttonConnect_Click(object sender, EventArgs e)
{
readData = "Conected to NYP Server ...";
msg();
//clientSocket.Connect("127.0.0.1", 8888);
clientSocket.Connect(textIP.Text, Convert.ToInt32(textPort.Text));
serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textName.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
Thread ctThread = new Thread(getMessage);
ctThread.Start();
}
private void buttonSend_Click(object sender, EventArgs e)
{
// Show msg box if no server is connected
if (serverStream == null)
{
MessageBox.Show("Please connect to a server first!");
return;
}
// Send text
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textSend.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
// Clear text
textSend.Text = "";
}
private void textDisplay_TextChanged(object sender, EventArgs e)
{
textDisplay.SelectionStart = textDisplay.Text.Length;
textDisplay.ScrollToCaret();
textDisplay.Refresh();
}
private void textSend_TextChanged(object sender, EventArgs e)
{
buttonSend.Enabled = !string.IsNullOrEmpty(textSend.Text);
}
}
}
if(string.IsNullOrEmpty(textIP.Text) || string.IsNullOrEmpty(textPort.Text) || string.IsNullOrEmpty(textName.Text))
{
MessageBox.Show("Please enter IP address, Port #, and Name");
}
else
{
//they entered stuff...so, try to connect..
}
You can use TcpClient.Connected property to check whether a connection is already established or not.
if(clientSocket.Connected){
.... show error message here
}
else{
... go ahead
}
Your form holds references to both a TcpClient and a NetworkStream instance. Both of these implement IDisposable, so that they must be disposed of explicitly. You must override the Dispose method of the form and dispose of these instances if they are not null.
after i am connected to the server, i click on the connect button again i get SocketException was unhandled on clientSocket.Connect("127.0.0.1", 8888); How to solve this?
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.Net.Sockets;
using System.Threading;
namespace SocketClient
{
public partial class SocketClient : Form
{
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
NetworkStream serverStream = default(NetworkStream);
string readData = null;
public SocketClient()
{
InitializeComponent();
}
private void getMessage()
{
while (true)
{
serverStream = clientSocket.GetStream();
int buffSize = 0;
byte[] inStream = new byte[10025];
buffSize = clientSocket.ReceiveBufferSize;
serverStream.Read(inStream, 0, buffSize);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
readData = "" + returndata;
msg();
}
}
private void msg()
{
if (this.InvokeRequired)
this.Invoke(new MethodInvoker(msg));
else
textDisplay.Text = textDisplay.Text + Environment.NewLine + " >> " + readData;
}
private void buttonConnect_Click(object sender, EventArgs e)
{
readData = "Conected to NYP Chat Server ...";
msg();
clientSocket.Connect("127.0.0.1", 8888);
serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textName.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
Thread ctThread = new Thread(getMessage);
ctThread.Start();
}
private void buttonSend_Click(object sender, EventArgs e)
{
// Show msg box if no server is connected
if (serverStream == null)
{
MessageBox.Show("Please connect to a server first!");
return;
}
// Send text
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textSend.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
// Clear text
textSend.Text = "";
}
private void textDisplay_TextChanged(object sender, EventArgs e)
{
textDisplay.SelectionStart = textDisplay.Text.Length;
textDisplay.ScrollToCaret();
textDisplay.Refresh();
}
private void textSend_TextChanged(object sender, EventArgs e)
{
buttonSend.Enabled = !string.IsNullOrEmpty(textSend.Text);
}
}
}
You can't connect clientSocket more than once. What do you expect to happen when you click the button the second time?
You could check the state of the socket and if it's connected then don't attempt another connection. Or put some exception handling in.