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.
Related
In the following code, the messages from the server are received on one thread (inside while loop). And, the messages to the server are sent on main GUI thread (on sendButton_Click)
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
namespace SimulatedClient
{
public partial class ClientForm : Form
{
TcpClient clientSocket = new TcpClient();
NetworkStream serverStream = default(NetworkStream);
string readdata = null;
public ClientForm()
{
InitializeComponent();
}
private void connectButton_Click(object sender, EventArgs e)
{
clientSocket.Connect(hostTextbox.Text, Int32.Parse(portTextBox.Text));
Thread ctThread = new Thread(getMessages);
ctThread.Start();
}
public void getMessages()
{
string returnData;
while (true)
{
serverStream = clientSocket.GetStream();
var buffersize = clientSocket.ReceiveBufferSize;
byte[] instream = new byte[buffersize];
serverStream.Read(instream, 0, buffersize);
returnData = System.Text.Encoding.ASCII.GetString(instream);
readdata = returnData;
UpdateReceivedPressureLabelText(readdata);
//msg();
}
}
void UpdateReceivedPressureLabelText(string value)
{
Action action = () => incomingTextBox.Text = value;
this.Invoke(action);
}
//private void msg()
//{
// if (this.InvokeRequired)
// {
// this.Invoke(new MethodInvoker(msg));
// }
// else
// {
// incomingTextBox.Text = readdata;
// }
//}
private void sendButton_Click(object sender, EventArgs e)
{
byte[] outstream = Encoding.ASCII.GetBytes(outgoingTextBox.Text);
serverStream.Write(outstream, 0 , outstream.Length);
serverStream.Flush();
}
}
}
QUESTION: Is it ok to do so i.e. is it ok to receive messages using one thread and send messages on another thread for the same clientSocket? The program is working but I am not sure if it could lead to some problem?
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).
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.
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