您的位置:首页 > 其它

Socket 同步和异步模式

2016-04-21 15:04 477 查看
学习socket 的一些笔记,希望和大家一起讨论 。

一.什么是socket

  所谓socket通常也称作"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。 以J2SDK-1.3为例,Socket和ServerSocket类库位于java .net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。

二 .开发原理:

 服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。   客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP网络编程,必须理解Socket接口。
Socket接口设计者最先是将接口放在Unix操作系统里面的。如果了解Unix系统的输入和输出的话,就很容易了解Socket了。网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符。Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。

三.简单的socket 同步代码,目前代码没有上服务器测试,不知道同步和异步的效果怎么样!

需求

1.客户端是公司内部的机器200台计算机。

2.可以同时连接,长连接。

3.服务器接受到客户端发来的信息,发送 socket数据 发送给总公司socket服务器 ,总公司返回数据。



socket 同步简单代码



public class Server

{

static void Main(string[] args)

{

IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);

//创建 socket Tcp

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

try

{

listener.Bind(localEndPoint);

listener.Listen(10);

while (true)

{

Socket connection = listener.Accept();

SocketProxy sp = new SocketProxy(connection);

Thread thread = new Thread(new ThreadStart(sp.TcpSendData));

thread.Name = connection.RemoteEndPoint.ToString();

thread.Start();

}

}

catch (Exception ex)

{

Console.WriteLine(ex.StackTrace);

}

}

}

public class SocketProxy

{

private Socket _socket;

public SocketProxy(Socket connection)

{

this._socket = connection;

}

public void TcpSendData()

{

byte[] bytes;

string data = string.Empty;

while (true)

{

bytes = new byte[1024];

// Receive client data

int bytesRec = this._socket.Receive(bytes);

// convert bytes to string

data = Encoding.ASCII.GetString(bytes, 0, bytesRec);

Console.WriteLine(data);

}

}

}

异步代码

internal class SocketServer

{

static void Main(string[] args)

{

SocketTcpListener listener = new SocketTcpListener();

listener.StartListening();

}

}

internal class SocketTcpListener

{

public static ManualResetEvent allDone = new ManualResetEvent(false);

//开始监听

public void StartListening()

{

//Data buffer for incoming data.

byte[] bytes = new Byte[1024];

//Establish the local endpoint for the socket.

//The DNS name of the computer

//running the listener is "host.contoso.com".

//IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());

IPAddress ipAddress = IPAddress.Parse("127.0.0.1");

IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 9050);

// Create a TCP/IP socket.

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

// Bind the socket to the local endpoint and listen for incoming connections.

try

{

listener.Bind(localEndPoint);

listener.Listen(10);

while (true)

{

// Set the event to nonsignaled state.

allDone.Reset();

// Start an asynchronous socket to listen for connections.

Console.WriteLine("Waiting for a connection");

StateObject state = new StateObject();

listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

// Wait until a connection is made before continuing.

allDone.WaitOne();

}

}

catch (Exception e)

{

Console.WriteLine(e.ToString());

}

}

//异步接受

private static void AcceptCallback(IAsyncResult ar)

{

// Signal the main thread to continue.

allDone.Set();

// Get the socket that handles the client request.

Socket listener = (Socket)ar.AsyncState;

Socket handler = listener.EndAccept(ar);

// Create the state object.

StateObject state = new StateObject();

state.workSocket = handler;

Array.Clear(state.buffer, 0, state.buffer.Length); // 清空缓存,避免脏读

handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);

}

//异步读取

public static void ReadCallback(IAsyncResult ar)

{

String content = String.Empty;

String resultdata = string.Empty;

// Retrieve the state object and the handler socket

// from the asynchronous state object.

StateObject state = (StateObject)ar.AsyncState;

Socket handler = state.workSocket;

// Read data from the client socket.

int bytesRead = handler.EndReceive(ar);

if (bytesRead > 0)

{

// There might be more data, so store the data received so far.

// state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

// Check for end-of-file tag. If it is not there, read

// more data.

content = Encoding.ASCII.GetString(state.buffer, 0, bytesRead);

Array.Clear(state.buffer, 0, state.buffer.Length); // 清空缓存,避免脏读

Console.WriteLine(content);

if (content.Length > -1)

{

// All the data has been read from the

// client. Display it on the console.

//Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content);

// Echo the data back to the client.

//SocketTcpClient.CreateSocketObjest();

// get caac data

// 0 如果是第一次,需要创建socket对象,发送登陆信息,匹配出用户名(<name,socket>),存放到集合

// 1.如果用户存在,需要使用用户名来匹配socket对象,如果没有连接配置,需要创建socket对象,保存到集合以便下次使用连接对象,避免再次的登陆

// 2.发送数据完,远程服务器会返回信息给Socket Server

// 3.Socket Server 返回信息给 Clinet

state.ResultData = content;

state.SocketName = "Jackyong";

resultdata =SocketTcpClient.Send(handler, content);

// send client

//Send(handler, resultdata);

Send(state);

}

//else

//{

// // Not all data received. Get more.

// handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReadCallback), state);

//}

}

}

//发送数据

private static void Send(StateObject state)

{

Array.Clear(state.buffer, 0, state.buffer.Length); // 清空缓存,避免脏读

// Convert the string data to byte data using ASCII encoding.

byte[] byteData = Encoding.ASCII.GetBytes(state.ResultData);

// Begin sending the data to the remote device.

state.workSocket.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), state);

}

// 异步发送数据给client

private static void SendCallback(IAsyncResult ar)

{

try

{

// Retrieve the socket from the state object.

// Socket handler = (Socket)ar.AsyncState;

StateObject state = (StateObject)ar.AsyncState;

// Complete sending the data to the remote device.

int bytesSent = state.workSocket.EndSend(ar);

// if detect exceptoin socket shut down /close

// handler.Shutdown(SocketShutdown.Both);

// handler.Close();

// continue to listener

//StateObject state = new StateObject();

//state.workSocket = handler;

Array.Clear(state.buffer, 0, state.buffer.Length); // 清空缓存,避免脏读

state.workSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);

}

catch (Exception e)

{

Console.WriteLine(e.ToString());

}

}

}

internal class SocketTcpClient

{

/// <summary>

/// create socket object ,client send server

/// </summary>

/// <param name="command">command</param>

/// <returns>data</returns>

public static Socket CreateSocketObjest()

{

//需要存储这个连接对象

string receivemsg = string.Empty;

byte[] data = new byte[1024];

string IP = "127.0.0.1";

int Port = 9050;

IPEndPoint ie = new IPEndPoint(IPAddress.Parse(IP), Port);//服务器的IP和端口

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

try

{

//因为客户端只是用来向特定的服务器发送信息,所以不需要绑定本机的IP和端口。不需要监听。

client.Connect(ie);

}

catch (SocketException e)

{

//close socket and writing error exception

Console.WriteLine(e.ToString());

}

return client;

}

/// <summary>

/// client send command server

/// </summary>

/// <param name="client">socket</param>

/// <param name="command">command</param>

/// <returns>data</returns>

public static string Send(Socket client, string command)

{

byte[] data = new byte[1024];

string result = string.Empty;

//send command

ClientSendDataServer(client, command);

if (client.Poll(-1, SelectMode.SelectRead))

{ //如果传递过来的是string.empty 字符串也是0

int recv = client.Receive(data);

if (recv == 0)

{

//socket连接已断开

}

result = Encoding.ASCII.GetString(data, 0, recv);

Console.WriteLine(result);

}

return result;

}

/// <summary>

/// client to server

/// </summary>

/// <param name="handler">socket </param>

/// <param name="data">comand</param>

private static void ClientSendDataServer(Socket client, String command)

{

// Convert the string data to byte data using ASCII encoding.

byte[] byteData = Encoding.ASCII.GetBytes(command);

// Begin sending the data to the remote device.

client.Send(byteData);

}

}

/// <summary>

/// 存放客户端与总公司的登陆信息

/// </summary>

internal class SocketUser

{

private System.Collections.Generic.Dictionary<string, Socket> _sockets;

public SocketUser()

{

_sockets = new Dictionary<string, Socket>();

}

/// <summary>

/// select client user

/// </summary>

/// <param name="key"></param>

/// <returns></returns>

public Socket Find(string key)

{

Socket socket = null; ;

if (key == null || key == string.Empty)

{

}

if (_sockets[key] != null)

{

socket = _sockets[key] as Socket;

}

return socket;

}

/// <summary>

/// add client in sockets

/// </summary>

/// <param name="key"></param>

/// <param name="sk"></param>

public void Add(string key, Socket sk)

{

_sockets.Add(key, sk);

}

/// <summary>

/// Remove client user

/// </summary>

/// <param name="key"></param>

public void Remove(string key)

{

_sockets.Remove(key);

}

}

// socket state
internal class StateObject

{

// socket name

public string SocketName { get; set; }

// Client socket.

public Socket workSocket = null;

// Size of receive buffer.

public const int BufferSize = 1024;

// Receive buffer.

public byte[] buffer = new byte[BufferSize];

// Received data string.

public string ResultData { get; set; }

}

出处 http://www.cnblogs.com/liuyong/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: