1 Socket Communication in C#. 2 How Sockets make communication? 1. Socket is a basic object that can...

34
1 Socket Communication in C#

Transcript of 1 Socket Communication in C#. 2 How Sockets make communication? 1. Socket is a basic object that can...

1

Socket Communication in C#

2

How Sockets make communication?1. Socket is a basic object that can do net communication.

All net communications are build on Socket operation.

2. In server side, object TcpLinstener is running at an HTTP port and standing by to listen for the calls from Internet. (TcpLinstener is called ServerSocket in Java)

3. In a client side, client Socket call TcpLinstener by web server IP and port

4. OnceTcpLinstener got call, it will execute function accept() and create a socket object in server side to take care communication

5. All socket net communication is use data stream.

6. Object TcpLinstener can go back and listen again.

3

Socket

TcpListener

Socket

Server side

HTTP Port

Initial call

accept()

Client side

4

Socket Constructor Socket ( AddressFamily addressFamily,

SocketType socketType,

ProtocolType protocolType ) Usual code is:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );

Its main methods are

1. Connect (IPEndPoint)

2. Send(byte[ ])

3. Receive(byte[ ])

4. Close()

5

Connect to a server by IP & Port# In order to make a connection we make an IPEndPoint object of

the remote server first. The process is the following:

IPHostEntry IpEntry = Dns.GetHostByAddress("129.7.127.103");IPAddress hostAddress = IpEntry.AddressList[0];IPEndPoint hostEndPoint = new IPEndPoint(hostAddress, 8001);socket.Connect(hostEndPoint);

Remarks:1. Dns is a class that deals with the domain names issues.2. If use the remote server name, then we have to use code like

IPHostEntry IpEntry = Dns.GetHostByName("www.nba.com");

3. One PC could have multiple IPs, but the above code will get an IPAddress object for string "129.7.127.103".4. Number 8001 is the port number of the remote server.

6

Send Data All data in net communication must be of type byte array.

Therefore we must use class ASCIIEncoding object to convert string to bytes and vise versa.

ASCIIEncoding asciiEnc = new ASCIIEncoding();String str = Console.ReadLine();byte[] binData = asciiEnc.GetBytes(str);socket.Send(binData);

Also we can use the following code to control the length of out data

socket.Send(binData, 0, binData.Length, SocketFlags.None);

7

Receive Data Receiving data from net is similar to sending data.

After receiving the binary data, use ASCIIEncoding object to convert it to string.

ASCIIEncoding asciiEnc = new ASCIIEncoding();byte[] binData = new byte[255];int k = socket.Receive(binData); String str = asciiEnc.GetString(binData,0, k);

Integer k is the total bytes received. If the input data is longer then the length of binData, some data could be lost. To prevent that case, we use the following code to control the length of input data no more than 255.

socket. Receive(binData, 0, binData.Length, SocketFlags.None); If k==0, the connection to the server is lost.

8

Use TcpClient object Like Socket, class TcpClient object can do TCP NetWork

communication too. The connection code is very simple:

TcpClient tcpClient = new TcpClient();tcpClient.Connect("129.7.127.103",8001);

However, it must use a Stream object to read and write.

ASCIIEncoding asciiEnc = new ASCIIEncoding();String str = Console.ReadLine();byte[] binData = asciiEnc.GetBytes(str);Stream stream = tcpClient.GetStream();stream.Write(binData, 0, binData.Length); // send data outReceiving code is

byte[] binDataIn = new byte[255];int k=stream.Read(binDataIn, 0, 255); //receive data

9

Server side TcpListener objectIn server side , we use class TcpListener object to build the connection to the client socket or TcpCliet object.

IPAddress ipAddr = IPAddress.Parse("129.7.127.103"); TcpListener netListener = new TcpListener(ipAddr, 8001);netListener.Start(); // start to listen

String ipNum = Dns.GetHostByName().AddressList[0].ToString().

"129.7.127.103" is the IP number of the server. If the server only has one IP number, then we can get it by code:

Once client side calls, it will trig the following function and generate a socket object to do communication.

Socket socket = netListener.AcceptSocket();

If no calls sent from client sides, this function will be standing by and waiting for the call from client side

10

Client Socket exampleusing System;using System.IO;using System.Net;using System.Text;using System.Net.Sockets;

public class client {public static void Main() {

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );

try{

IPHostEntry IpEntry = Dns.GetHostByAddress("192.168.1.103");IPAddress hostAddress = IpEntry.AddressList[0];IPEndPoint hostEndPoint = new IPEndPoint(hostAddress, 8001);Console.WriteLine("Connecting.....");socket.Connect(hostEndPoint);

11

if(socket.Connected) Console.WriteLine("Connected");Console.Write("Enter the string to be transmitted : ");ASCIIEncoding asciiEnc= new ASCIIEncoding();while(true){

string str=Console.ReadLine();if(str.ToLower() =="quit") break;byte[] binDataOut = asciiEnc.GetBytes(str);socket.Send(binDataOut, 0, binDataOut.Length,SocketFlags.None); byte[] binDataIn=new byte[255];int k = socket.Receive(binDataIn, 0, 255 , SocketFlags.None); string msg = asciiEnc.GetString(binDataIn, 0, k);Console.Write(msg);

}socket.Close();

}catch (Exception e) { Console.WriteLine("Error..... " + e.StackTrace); }Console.ReadLine();

} }

12

Client TcpClient exampleusing System;using System.IO;using System.Net;using System.Text;using System.Net.Sockets;

public class client {public static void Main() { TcpClient tcp = new TcpClient(); try {

Console.WriteLine("Connecting.....");tcp.Connect("192.168.1.103", 8001); Console.WriteLine("Connected");Console.WriteLine("Enter the string to be transmitted : ");ASCIIEncoding asciiEnc= new ASCIIEncoding();Stream stream = tcp.GetStream();

13

while(true){

string str=Console.ReadLine();if(str.ToLower() =="quit") break;byte[] binDataOut = asciiEnc.GetBytes(str);stream. Write(binDataOut, 0, binDataOut.Length);byte[] binDataIn=new byte[255];int k = stream.Read(binDataIn,0,255);string msg = asciiEnc.GetString(binDataIn, 0, k);Console.Write(msg);

}Tcp.Close();Console.ReadLine();

} // end of trycatch (Exception e) { Console.WriteLine("Error..... " + e.StackTrace); Console.ReadLine(); }

} }

14

Server Socket exampleusing System;using System.Net;using System.Text;using System.Net.Sockets;

public class server{ public static void Main() { bool connected =false;

try{IPAddress ipAddr = IPAddress.Parse("192.168.1.103"); TcpListener myListener = new TcpListener(ipAddr,8001);

myListener.Start();Console.WriteLine("The server is running at port: " + myListener.LocalEndpoint);Console.WriteLine("Waiting for a connection.....");Socket socket = myListener.AcceptSocket();

Console.WriteLine("Connection accepted from" + socket.RemoteEndPoint)

15

connected =true;byte[] binDataIn = new byte[255];Console.WriteLine("The message from client side... ");while(true){

int k=socket.Receive(binDataIn);if(k==0) break;ASCIIEncoding asciiEnc = new ASCIIEncoding();string msg = asciiEnc.GetString(binDataIn, 0, k);byte [] binOut = new byte [k];for(int i=0; i<k; i++)binOut[i] = binDataIn[k-i-1];socket.Send(binOut);Console.WriteLine(msg);

}socket.Close();myListener.Stop();}

catch (Exception e) { if(!connected)Console.WriteLine("Error..... " + e.ToString() ); }Console.WriteLine("\nClient closed connection");Console.ReadLine();

} }

16

Output

17

Multiple Threading1. From last example, we can see that TcpListener build

connection while sockets do communication2. Therefore one TcpListener can serve for many client sockets.

To this purpose we must use multiple thread.3. Thread is a connection between program and operating

system. With a thread, system can arrange CPU time to execute the program instructions.

4. Any program has a natural thread that from Main() function.5. Some program operation will control thread until it finished.

Such as play a music. If the program only has one thread, during the music playing time, the window cannot be moved or resized.

6. TcpListener needs thread for standing by and listening. Socket needs thread to do communication. Therefore we need multiple threads for socket communications

18

Add Thread object1. First we must add

using system.Threading;2. Create a function in the class, which must be void and no

argument, suppose it is:private void foo() {…}

3. Then create a Thread object in the following way:

Thread t = new Thread(new ThreadStart(foo));

t.Start();

4. Then function foo() will get a new Thread

5. We can call t.Suspend() and t.Resume().

6. To destroy a thread, call t.Abort()

19

Communication classpublic class Communication{

Socket socket=null;int n; public Communication(Socket sock, int k){ socket = sock; n = k; }

public void Talk(){

byte[] binDataIn = new byte [255];Console.WriteLine("The socket " + n + " begin to work... ");try{

while(true){

int k=socket.Receive(binDataIn);If (k==0) break; // if client closed

20

ASCIIEncoding asciiEnc = new ASCIIEncoding();string msg = asciiEnc.GetString(binDataIn,0,k);

byte [] binOut = new byte [k];for(int i=0; i<k; i++){

binOut[i] = binDataIn[k-i-1];}socket.Send(binOut);Console.WriteLine("from client " + n +" " +msg);

}}catch(Exception) { } // if client shut downConsole.WriteLine("Client " + n +" Disconnected");

socket.Close();}

}}

21

How to Assign Thread ?int count = 0;while(true){

Socket socket = myListener.AcceptSocket();count++;Console.WriteLine("Connection " + count + " accepted from

"+socket.RemoteEndPoint);Communication com = new Communication(socket, count);Thread t = new Thread(new ThreadStart(com.Talk));t.Start();

}// this is listening loop

After call t.Start(), the thread will assign to function Talk() of class Communication object com.

22

Communication between ClientsIn this case, we must put all server side sockets object in a container, so that we can send message to every client by using this container.

Client socket 1

Client socket 2

Socket 1

Socket 2

ArrayList

Server side

23

Use ArrayList to store objectWe must store all socket in ArrayList object that can be accessed by all threads. The basic methods of ArrayList object are:

Add(object obj);Remove(object obj);

ArrayList list = new ArrayList(); Communication com1 = new Communication(socket, count);List.Add(com1);

Communication com2 =( Communication) list[3];

Its property Count is the total objects in the list.To access its object use index function []. However, we must do casting operation to get original class object.

24

Synchronized operation1. When some data is shared by multiple threads, we must do

Synchronized operation. For example if the shared data is written in one thread, we must block all writing process from other threads. Sometimes, we even need to block reading process.

2. In C#, we can use class ReaderWriterLock object to do so.

ReaderWriterLock rw = new ReaderWriterLock()static public void remove(object obj){

rw.AcquireWriterLock(Timeout.Infinite); list.Remove(obj) ;rw.ReleaseWriterLock();

}

25

Server Broadcast exampleusing System;using System.Net;using System.Text;using System.Net.Sockets;using System.Collections; // for ArrayListusing System.Threading;

public class server{

static ArrayList list = new ArrayList(); static ReaderWriterLock rw = new ReaderWriterLock();

static public void remove(object obj){

rw.AcquireWriterLock(Timeout.Infinite); list.Remove(obj) ;rw.ReleaseWriterLock();

}

26

Server Broadcast examplestatic public void AddList(object obj){

rw.AcquireWriterLock(Timeout.Infinite); list.Add(obj) ;rw.ReleaseWriterLock();

}

static public void SendToAll(byte[] binData){

rw.AcquireWriterLock(Timeout.Infinite); for(int k = 0; k<list.Count; k++){

Communication com = (Communication)list[k]; Socket sock = com.socket;sock.Send(binData);

}rw.ReleaseWriterLock();

}

27

public static void Main() {

bool connected =false;int count =0;TcpListener myListener = null;try {

string hostName = Dns.GetHostName();IPHostEntry ipEntry = Dns.GetHostByName(hostName);myListener = new TcpListener(ipEntry.AddressList[0],8001);

myListener.Start();Console.WriteLine("The server is running at port: " +

myListener.LocalEndpoint);Console.WriteLine("Waiting for a connection.....");while(true) {

Socket socket=myListener.AcceptSocket();count++;Console.WriteLine("Connection " + count + " accepted from

"+socket.RemoteEndPoint);Communication com = new Communication(socket, count);AddList(com);

} }

28

catch (Exception e) {

if(!connected)Console.WriteLine("Error..... " + e.ToString() );}myListener.Stop();Console.WriteLine("\nClient closed connection");Console.ReadLine();

}

public class Communication{

public Socket socket=null;int n;public Communication(Socket sock, int k){

socket = sock;n = k;Thread t = new Thread (new ThreadStart (Talk));t.Start();

}

29

public void Talk(){

byte[] binDataIn = new byte [255];Console.WriteLine("The socket " + n + " begin to work... ");

try {while(true) {

int k=socket.Receive(binDataIn);if(k==0) break; // if client closedASCIIEncoding asciiEnc = new ASCIIEncoding();string msg = asciiEnc.GetString(binDataIn,0,k);msg = "from client " + n +": " + msg;byte[] binDataOut = asciiEnc.GetBytes(msg); SendToAll(binDataOut);Console.WriteLine(msg);

}}catch(Exception) { }Console.WriteLine("Client " + n +" Disconnected");remove(this);socket.Close();

}}}

30

Client sideIn client side we need to add one thread to take care the messages from broadcasting.

using System;using System.IO;using System.Net;using System.Text;using System.Net.Sockets;using System.Threading ;

public class client{

static bool connected = false;static Socket socket = null;

31

public static void Main() {

Console.WriteLine("Please enter the Server IP address");string IP = Console.ReadLine();Console.WriteLine("Please enter the Server HTTP port number");string port = Console.ReadLine();int p;try{

p = Int32.Parse(port); }catch(Exception){

Console.WriteLine("Wrong port number");return;

}socket = new Socket(AddressFamily.InterNetwork,

SocketType.Stream, ProtocolType.Tcp );IPHostEntry IpEntry = Dns.GetHostByAddress(IP);IPAddress hostAddress = IpEntry.AddressList[0];IPEndPoint hostEndPoint = new IPEndPoint(hostAddress, p);Console.WriteLine("Connecting.....");

32

try {socket.Connect(hostEndPoint);

}catch(Exception) {Console.WriteLine("No connection to server\nPress enter to exit");Console.ReadLine(); return;}connected = socket.Connected;if(connected) Console.WriteLine("Connected");Console.WriteLine("Enter the string to be transmitted : ");ASCIIEncoding asciiEnc= new ASCIIEncoding();Thread t = new Thread(new ThreadStart(GetMsg));t.Start(); while(connected){

String str=Console.ReadLine();if(str.ToLower() =="quit") break;byte[] binData = asciiEnc.GetBytes(str);socket.Send(binData, 0, binData.Length, SocketFlags.None); socket.Close();

}}

33

catch (Exception e) {

Console.WriteLine("Error..... " + e.StackTrace);Console.ReadLine(); }

connected = false;}

static private void GetMsg(){

ASCIIEncoding asciiEnc= new ASCIIEncoding();while(connected){

byte[] bb=new byte[255];int k = socket.Receive(bb, 0, bb.Length , SocketFlags.None); string msg = asciiEnc.GetString(bb,0,k);Console.WriteLine( msg);

}}

}

34