Socket 阻塞模式
一. 两种I/O模式
阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序。套接字 默认为阻塞模式。可以通过多线程技术进行处理。
二.非阻塞模式:执行I/O操作时,Winsock函数会返回并交出控制权。这种模式使用 起来比较复杂,因为函数在没有运行完成就进行返回,会不断地返回 WSAEWOULDBLOCK错误。但功能强大。
为了解决这个问题,提出了进行I/O操作的一些I/O模型,下面介绍最常见的三种:
C# 代码
1.客户端
代码
class Client
{
static void Main(string[] args)
{
byte[] data = new byte[1024];
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
string ipadd = "127.0.0.1";
int port = 9050;
IPEndPoint ie = new IPEndPoint(IPAddress.Parse(ipadd), port);//服务器的IP和端口
try
{
//因为客户端只是用来向特定的服务器发送信息,所以不需要绑定本机的IP和端口。不需要监听。
client.Connect(ie);
}
catch (SocketException e)
{
Console.WriteLine(e.ToString());
return;
}
//发送给服务器连接成功
client.Send(Encoding.ASCII.GetBytes("client connection to server !"));
//接受客户端的信息,客户端会显示欢迎你来到北京
int recv = client.Receive(data);
string stringdata = Encoding.ASCII.GetString(data, 0, recv);
//显示服务器发送过来的信息
Console.WriteLine(stringdata);
data = new byte[1024];
Console.WriteLine("are you input message ?");
string input = Console.ReadLine();
if (input == "exit")
{
Console.WriteLine("disconnect from sercer");
client.Shutdown(SocketShutdown.Both);
client.Close();
}
if (input == "yes")
{
Console.WriteLine("input send message ");
input = Console.ReadLine();
//发送信息到服务器
client.Send(Encoding.ASCII.GetBytes(input));
recv = client.Receive(data);
stringdata = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine(stringdata);
}
}
}
{
static void Main(string[] args)
{
byte[] data = new byte[1024];
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
string ipadd = "127.0.0.1";
int port = 9050;
IPEndPoint ie = new IPEndPoint(IPAddress.Parse(ipadd), port);//服务器的IP和端口
try
{
//因为客户端只是用来向特定的服务器发送信息,所以不需要绑定本机的IP和端口。不需要监听。
client.Connect(ie);
}
catch (SocketException e)
{
Console.WriteLine(e.ToString());
return;
}
//发送给服务器连接成功
client.Send(Encoding.ASCII.GetBytes("client connection to server !"));
//接受客户端的信息,客户端会显示欢迎你来到北京
int recv = client.Receive(data);
string stringdata = Encoding.ASCII.GetString(data, 0, recv);
//显示服务器发送过来的信息
Console.WriteLine(stringdata);
data = new byte[1024];
Console.WriteLine("are you input message ?");
string input = Console.ReadLine();
if (input == "exit")
{
Console.WriteLine("disconnect from sercer");
client.Shutdown(SocketShutdown.Both);
client.Close();
}
if (input == "yes")
{
Console.WriteLine("input send message ");
input = Console.ReadLine();
//发送信息到服务器
client.Send(Encoding.ASCII.GetBytes(input));
recv = client.Receive(data);
stringdata = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine(stringdata);
}
}
}
2.服务端
代码
class server
{
static void Main(string[] args)
{
string message = "welcome to beijing !";
//用于缓存客户端所发送的信息,通过socket传递的信息必须为字节数组
byte[] data = new byte[1024];
//本机预使用的IP和端口
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(ipep);//绑定
listener.Listen(10);//监听
//当有可用的客户端连接尝试时执行,并返回一个新的socket,用于与客户端之间的通信
Socket client = listener.Accept();
//获取客户端的IP 和端口
IPEndPoint clientip = (IPEndPoint)client.RemoteEndPoint;
Console.WriteLine("Clinet IP ={0} Port={1}", clientip.Address, clientip.Port);
data = Encoding.ASCII.GetBytes(message);
client.Send(data, data.Length, SocketFlags.None);//发送信息
while (true)
{
try
{
data = new byte[1024];
client.Receive(data);
//打印出数据
Console.WriteLine(Encoding.ASCII.GetString(data, 0, data.Length));
//转换为大写后发送给client
message = Encoding.ASCII.GetString(data, 0, data.Length).ToUpper();
data = Encoding.ASCII.GetBytes(message);
//返回信息给客户端
client.Send(data, data.Length, SocketFlags.None);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Console.WriteLine("Disconnected from" + clientip.Address);
client.Close();
listener.Close();
}
}
{
static void Main(string[] args)
{
string message = "welcome to beijing !";
//用于缓存客户端所发送的信息,通过socket传递的信息必须为字节数组
byte[] data = new byte[1024];
//本机预使用的IP和端口
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(ipep);//绑定
listener.Listen(10);//监听
//当有可用的客户端连接尝试时执行,并返回一个新的socket,用于与客户端之间的通信
Socket client = listener.Accept();
//获取客户端的IP 和端口
IPEndPoint clientip = (IPEndPoint)client.RemoteEndPoint;
Console.WriteLine("Clinet IP ={0} Port={1}", clientip.Address, clientip.Port);
data = Encoding.ASCII.GetBytes(message);
client.Send(data, data.Length, SocketFlags.None);//发送信息
while (true)
{
try
{
data = new byte[1024];
client.Receive(data);
//打印出数据
Console.WriteLine(Encoding.ASCII.GetString(data, 0, data.Length));
//转换为大写后发送给client
message = Encoding.ASCII.GetString(data, 0, data.Length).ToUpper();
data = Encoding.ASCII.GetBytes(message);
//返回信息给客户端
client.Send(data, data.Length, SocketFlags.None);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Console.WriteLine("Disconnected from" + clientip.Address);
client.Close();
listener.Close();
}
}
出处:http://www.cnblogs.com/liuyong/
作者喜欢研究 Sql Server ,ASP.NET MVC , Jquery WCF 等技术,同时关心分布式架构的设计应用。转载请保留原文链接,谢谢!