In getting used to Sockets using Client server communication here is my code.
//server partl
try
{
IPAddress ipAd = IPAddress.Parse("127.0.0.1"); //use local m/c IP address, and use the same in the client
/* Initializes the Listener */
TcpListener myList = new TcpListener(ipAd, 8020);
/* Start Listeneting at the specified port */
myList.Start();
Socket s = myList.AcceptSocket();
Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);
byte[] b = new byte[100];
int k = s.Receive(b);
//Console.WriteLine("Recieved...");
//Writes to label1
for (int i = 0; i < k; i++)
label1.Text = b[i].ToString();
//ASCII endoing to use ACK.
ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes("The string was recieved by the server."));
Console.WriteLine("\nSent Acknowledgement");
/* clean up */
s.Close();
myList.Stop();
}
catch (Exception ex)
{
Console.WriteLine("Error..... " + ex.StackTrace);
}
//Client part
try
{
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("Connecting.....");
tcpclnt.Connect("127.0.0.1", 8020); // use the ipaddress as in the server program
Console.WriteLine("Connected");
Console.Write("Enter the string to be transmitted : ");
//gets the text from textbox
String str = textBox1.Text;
Stream stm = tcpclnt.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes(str);
Console.WriteLine("Transmitting.....");
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]));
tcpclnt.Close();
}
catch (Exception ex)
{
Console.WriteLine("Error..... " + ex.StackTrace);
}
}
I am using a form to communicate on local host and writing a one .cs file and want to show the text(from textbox) from Client-labelled portion to the label on server-labelled portion.
Any idea why its not showing output?. New to sockets !!!
When socket receives the data instead of loop simply use this:
if (k > 0)
label1.Text = Encoding.UTF8.GetString(b);
Also you can use this for simply send and receive data using TcpClient which is a wrapper around socket.
Related
I want to make a simple client-server application. The server waits for connection from clients. The client can send various queries (short strings of less than 100 char) to the server and the server should respond to these queries by sending strings or files.
I found code online that uses a tcpListener.AcceptSocket() and I can send and receive strings from server and code that uses tcpListener.AcceptTcpClient() and I can send files to a different server program.
Below there is a function for sending files via TcpIP and one for sending strings via TcpIP. How should the server code look like, to acommodate both functions? The server is a console program.
public void SendFileViaTCP(string sFile, string sIPAddress, int portNo)
{
byte[] sendingBuffer = null;
TcpClient client = null;
toolStripStatusLabel1.Text = "";
lbConnect.Items.Clear();
progressBar1.Value = 0;
Application.DoEvents();
NetworkStream networkStream = null;
int bufferSize = 5000;
string checksum = CalculateMD5(sFile);
lbConnect.Items.Add("File " + sFile + " checksum = " + checksum);
try
{
client = new TcpClient(sIPAddress, portNo);
toolStripStatusLabel1.Text = "Connected to the Server...\n";
networkStream = client.GetStream();
FileStream fileStream = new FileStream(sFile, FileMode.Open, FileAccess.Read);
long fsLength = fileStream.Length;
int nPackets = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(fsLength) / Convert.ToDouble(bufferSize)));
progressBar1.Maximum = nPackets;
Application.DoEvents();
int currentPacketLength;
for (int i = 0; i < nPackets; i++) {
if (fsLength > bufferSize) {
currentPacketLength = bufferSize;
fsLength -= currentPacketLength;
Application.DoEvents();
}
else {
currentPacketLength = Convert.ToInt32(fsLength);
}
sendingBuffer = new byte[currentPacketLength];
fileStream.Read(sendingBuffer, 0, currentPacketLength);
networkStream.Write(sendingBuffer, 0, (int)sendingBuffer.Length);
progressBar1.PerformStep();
Application.DoEvents();
}
toolStripStatusLabel1.Text = "Sent " + fileStream.Length.ToString() + " bytes to the server";
fileStream.Close();
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
finally {
networkStream.Close();
client.Close();
}
}
void SendString(string str, string sIPAddress, int portNo)
{
try {
TcpClient tcpClient = new TcpClient();
lbConnect.Items.Add("Connecting...");
Application.DoEvents();
// use the ipaddress as in the server program
var tsk = tcpClient.ConnectAsync(sIPAddress, portNo);
tsk.Wait(3000); // here we set how long we want to wait before deciding the server is not responding.
lbConnect.Items.Add("Connected");
lbConnect.Items.Add("Sending string: " + str);
Application.DoEvents();
Stream stream = tcpClient.GetStream();
ASCIIEncoding asen= new ASCIIEncoding();
byte[] ba=asen.GetBytes(str);
lbConnect.Items.Add("Transmitting...");
Application.DoEvents();
stream.Write(ba,0,ba.Length);
byte[] bb=new byte[100];
int k = stream.Read(bb,0,100);
string sResponse = string.Empty;
for (int i = 0; i < k; i++) {
sResponse += Convert.ToChar(bb[i]);
}
lbConnect.Items.Add(sResponse);
Application.DoEvents();
tcpClient.Close();
}
catch (Exception e) {
lbConnect.Items.Add("Error: " + e.StackTrace);
Application.DoEvents();
}
}
I'm creating a basic TicTacToe program to play against my friends across the internet (this is to learn the basics of network programming). The problem is that although the correct data is received by the client, when it tries to send data no data is sent, even though the code executes correctly.
Here is the client software:
string input;
Board board = new Board();
while (true)
{
TcpClient tcpclnt = new TcpClient();
tcpclnt.Connect("192.168.0.10", 5000);
byte[] b = new byte[1024];
NetworkStream ns = tcpclnt.GetStream();
int k = ns.Read(b, 0, 100);//recieve data from host
string sRecieve = string.Empty;
for (int i = 0; i < k; i++)
sRecieve += Convert.ToChar(b[i]);
Console.WriteLine(sRecieve);
input = Console.ReadLine();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes(input);
ns.Write(ba, 0, ba.Length);
tcpclnt.Close();
}
This is the server code (this is all that is running when the connection occurs):
TcpListener tcpList = new TcpListener(IPAddress.Any, 5000);
tcpList.Start();
Console.WriteLine("Waiting for valid connection");
Socket s = tcpList.AcceptSocket();
Console.WriteLine("Connection accepted from: " + s.RemoteEndPoint);
ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes(board.ToString()));//send data
Console.WriteLine("sent board layout");
byte[] b = new byte[1024];
Console.WriteLine("Waiting for next play");
int k = s.Receive(b);
Console.WriteLine("Received next play");
string sInput = string.Empty;
for (int i = 0; i < k; i++)
input += Convert.ToChar(b[i]);
I have a simple implementation of a TCP client server relationship. But their are few problems that i don't know how to fix. here is the code of the Client and Server:
Client and Server are both separated. Each one of them is written i different project.
public void Server()
{
try
{
IPAddress IP = IPAddress.Parse("127.0.0.1");
TcpListener Listener = new TcpListener(IP, 8001);
Listener.Start();
Socket s = Listener.AcceptSocket();
byte[] b = new byte[100];
int k = s.Receive(b);
for (int i = 0; i < k; i++){
ConsoleWpfGUI.Write(Convert.ToChar(b[i]));
}
ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes("The string:"+strTemp+ " was recieved by the server."));
s.Close();
Listener.Stop();
}
catch (Exception e) {
ConsoleWpfGUI.WriteLine("Error..... " + e.StackTrace);
}
}
}
public void Client()
{
try
{
TcpClient tcpclnt = new TcpClient();
tcpclnt.Connect("127.0.0.1", 8001);
String str = InputString.Text;
Stream stm = tcpclnt.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++)
ConsoleWpfGUI.Write(Convert.ToChar(bb[i]));
tcpclnt.Close();
}
catch (Exception e)
{
ConsoleWpfGUI.Text = "No connection..... ";
}
}
}
1. The listener does not work properly, i.e. the listening captures the GUI thread (serv and client classes that i use in wpf). and not running in a separate thread, resulting with the application being unresponsive once “listen” (Buttoon that start the class serv) is pressed.
Only with the 1st call being replied it's work,the next send is fails. resulting not dealing with the socketing and passing to a separate thread right on the server side.
How can I use Thread that the serv class will not stuck the app.
And how i can use properly with socketing and passing threads that will make my app work more then ones.
Thanks!
You need to use separate threads for "Client" and "Server". You cannot run both in one UI thread. Because listening will block your UI thread and hence neither Client or Server can run correctly.
You can find many resources over internet about Client Server practice examples. Just use Threading, Background Workers for accomplish your task
Good Articles :
http://csharp.net-informations.com/communications/csharp-socket-programming.htm
http://www.codeproject.com/Tips/607801/SimpleplusChatplusprogramplusinplusC ,
http://www.codeproject.com/Articles/99143/BackgroundWorker-Class-Sample-for-Beginners
I ran your code. Try running following on TWO Console programs - Rub them Separately and run Server first
Client -
try
{
TcpClient tcpclnt = new TcpClient();
tcpclnt.Connect("127.0.0.1", 8001);
String str = "From CLient";
Stream stm = tcpclnt.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]));
tcpclnt.Close();
}
catch (Exception)
{
Console.WriteLine("No connection..... ");
}
Console.WriteLine("Transmission end.");
Console.ReadKey();
Server -
string strTemp = "Hello from server";
try
{
IPAddress IP = IPAddress.Parse("127.0.0.1");
TcpListener Listener = new TcpListener(IP, 8001);
Listener.Start();
Socket s = Listener.AcceptSocket();
byte[] b = new byte[100];
int k = s.Receive(b);
for (int i = 0; i < k; i++)
{
Console.Write(Convert.ToChar(b[i]));
}
ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes("The string:" + strTemp + " was recieved by the server."));
s.Close();
Listener.Stop();
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
}
Console.ReadKey();
Note - Just paste them inside Main method and try, you will need Sytem.IO import in Visual Studio ()
Basically what i am stuck at is , i want my client to send data continously and server to read from client as it sends, like when i send "2" it should read "2" and display and so on it should continue to read as long as i send from the client, i can stop or exit whenever i press some different character,.
what i have acheived is not continous, i send from client 2 and server receives 2 and then it is stopped, i want to send them continously , i am pasting below my code,
client.cs
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace Client
{
class Program
{
const int port = 8001;
const string ip = "127.0.0.1";
const int maxBuffer = 100;
static void Main(string[] args)
{
try
{
while (true)
{
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("Connecting.....");
tcpclnt.Connect("127.0.0.1", 8001);
// use the ipaddress as in the server program
Console.WriteLine("Connected");
Console.Write("Enter the string to be transmitted : ");
String str = Console.ReadLine();
Stream stm = tcpclnt.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes(str);
Console.WriteLine("Transmitting.....");
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]));
Console.ReadLine();
tcpclnt.Close();
}
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
}
}
}
}
server.cs
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Server
{
class Program
{
const int port = 8001;
const string ip = "127.0.0.1";
const int maxBuffer = 100;
static void Main(string[] args)
{
try
{
IPAddress ipAd = IPAddress.Parse("127.0.0.1");
// use local m/c IP address, and
// use the same in the client
while (true)
{
/* Initializes the Listener */
TcpListener myList = new TcpListener(ipAd, 8001);
/* Start Listeneting at the specified port */
myList.Start();
Console.WriteLine("The server is running at port 8001...");
Console.WriteLine("The local End point is :" +
myList.LocalEndpoint);
Console.WriteLine("Waiting for a connection.....");
Socket s = myList.AcceptSocket();
Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);
byte[] b = new byte[100];
int k = s.Receive(b);
Console.WriteLine("Recieved...");
for (int i = 0; i < k; i++)
Console.Write(Convert.ToChar(b[i]));
ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes("The string was recieved by the server."));
Console.WriteLine("\nSent Acknowledgement");
Console.ReadLine();
/* clean up */
s.Close();
myList.Stop();
}
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
}
}
}
}
Any help will be appreciated
Thanks :)
By using MultiThread you can send and receive message between client and server continuously.
Server side example:
IPAddress[] ipAdd = Dns.GetHostAddresses("192.168.1.38");
IPAddress ipAddress = ipAdd[0];
TcpListener serverSocket = new TcpListener(ipAddress, 8888);
TcpClient clientSocket = default(TcpClient);
int counter = 0;
serverSocket.Start();
notifyIcon.ShowBalloonTip(5000, "Server Notification", " >> Server Started.", wform.ToolTipIcon.Info);
counter = 0;
while (true)
{
counter += 1;
clientSocket = serverSocket.AcceptTcpClient();
byte[] bytesFrom = new byte[10025];
string dataFromClient = null;
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
dataFromClient = Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
if (clientsList.ContainsKey(dataFromClient))
{
continue;
}
else
{
clientsList.Add(dataFromClient, clientSocket);
}
string onlineUsers = "";
foreach (DictionaryEntry item in clientsList)
{
onlineUsers += item.Key.ToString() + ";";
}
onlineUsers = onlineUsers.Remove(onlineUsers.Length - 1);
Broadcast.BroadcastSend(dataFromClient + " joined. |" + onlineUsers, dataFromClient, ref clientsList, false, false);
notifyIcon.ShowBalloonTip(5000,"Client Notification", dataFromClient + " joined.", wform.ToolTipIcon.Info);
HandleClient client = new HandleClient();
client.StartClient(clientSocket, dataFromClient, clientsList, notifyIcon);
}
More details
Ignore my earlier answer
The problem is that the server is waiting for user response in console after sending acknowledgement.
Console.ReadLine();
Just comment out this line in your original program.
And add a exit condition by checking the input.
Also as the previous poster suggest, make it thread based if you want multiple clients connecting to this server simultaneously.
I am trying to create a very basic little client server application, but I can only get it to work locally on my own machine.
Server code:
int d = 0;
try
{
for (AdministratorPort = 8000; d < 1; AdministratorPort++)
{
IPAddress ipAddress = IPAddress.Parse("220.101.27.107");
TcpListener tcpListener = new TcpListener(ipAddress, AdministratorPort);
tcpListener.Start();
// Display results.
Label label = new Label();
label.Text = "The server is connected to, and running on Port: 8001." + Environment.NewLine +
tcpListener.LocalEndpoint + Environment.NewLine +
"Team Share Server is now awaiting new connections.";
label.AutoSize = true;
label.Location = new Point(4, 15);
panel.Controls.Add(label);
panel.AutoScroll = true;
Socket socket = tcpListener.AcceptSocket();
label.Text += Environment.NewLine +
"Connection accepted from: " + socket.RemoteEndPoint;
byte[] Message = new byte[100];
int k = socket.Receive(Message);
label.Text += Environment.NewLine +
"Message received from server.";
for(int i = 0; i < k; i++)
label.Text += Environment.NewLine +
Convert.ToChar(Message[i]);
ASCIIEncoding asciiEncoding = new ASCIIEncoding();
socket.Send(asciiEncoding.GetBytes("The string was received by the server."));
label.Text += Environment.NewLine +
"Acknowledgement sent to client.";
socket.Close(10);
tcpListener.Stop();
d = 1;
}
}
catch (Exception e) {
d = 0;
File.WriteAllText("this.txt", e.StackTrace);
}
Client code:
int d = 0;
try
{
for (int port = 8000; d < 1; port++)
{
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("TRYING to connect...");
tcpclnt.Connect("220.101.27.107", port); // use the ipaddress as in the server program
Console.WriteLine("Connected, finally.");
Console.Write("Enter the string to be transmitted : ");
String str = Console.ReadLine();
Stream stm = tcpclnt.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes(str);
Console.WriteLine("Transmitting.....");
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]));
tcpclnt.Close();
d = 1;
}
}
catch (Exception e)
{
d = 0;
Console.Write("oh no..... " + e.StackTrace + " " + e.Data + " " + e.Message.ToString());
Console.Read();
}
What am I doing wrong?
EDIT:
the errors i am getting "connection timed out cos host didnt respond" or most of the time i get "host machine actively refused connection" and also the most recent error was : "connection attempt failed because the connected party did not respond properly after a period of time, or established connection failed because connected host has failed to respond 220.101.27.107".
Have you tried unlocking the port?
You can erase the IPAddress object on the server and also :
Replace
TcpListener tcpListener = new TcpListener(ipAddress, AdministratorPort);
with
TcpListener tcpListener = new TcpListener(IPAddress.Any, AdministratorPort);