经过学习,基本上掌握了如何使用TCP套接字发送消息。因为TCP套接字是面向连接的,在数据传输之前,发送和接收的双方都必须建立好连接。数据以数据流的形式发送到远程机器上,因此在TCP会话中消息是没有边界的。
在这种使用TCP协议的环境中,不能保护消息的边界,因此在编写网络层的TCP应用时,必须考虑如何识别单个消息。
为了解决消息边界问题常用技巧:
1、永远发送固定长度的消息
2、将消息尺寸与消息一起发送
3、使用标记系统分隔消息
使用C#流的ReadLine来区分消息
服务器端程序:
static void Main(string[] args)
{
string data;
string input;
IPAddress ip = IPAddress.Parse("127.0.0.1");
IPEndPoint ipEnd = new IPEndPoint(ip, 5566);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
socket.Connect(ipEnd);
}
catch (SocketException e)
{
Console.Write("Fail to connect server");
Console.Write(e.ToString());
return;
}
NetworkStream ns = new NetworkStream(socket);
StreamReader sr = new StreamReader(ns);
StreamWriter sw = new StreamWriter(ns);
data = sr.ReadLine();
Console.WriteLine(data);
while (true)
{
input = Console.ReadLine();
if (input == "exit")
break;
sw.WriteLine(input);
sw.Flush();
data = sr.ReadLine();
Console.WriteLine(data);
}
Console.Write("disconnect from server");
sr.Close();
sw.Close();
ns.Close();
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
{
string data;
string input;
IPAddress ip = IPAddress.Parse("127.0.0.1");
IPEndPoint ipEnd = new IPEndPoint(ip, 5566);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
socket.Connect(ipEnd);
}
catch (SocketException e)
{
Console.Write("Fail to connect server");
Console.Write(e.ToString());
return;
}
NetworkStream ns = new NetworkStream(socket);
StreamReader sr = new StreamReader(ns);
StreamWriter sw = new StreamWriter(ns);
data = sr.ReadLine();
Console.WriteLine(data);
while (true)
{
input = Console.ReadLine();
if (input == "exit")
break;
sw.WriteLine(input);
sw.Flush();
data = sr.ReadLine();
Console.WriteLine(data);
}
Console.Write("disconnect from server");
sr.Close();
sw.Close();
ns.Close();
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
客户端程序:
static void Main(string[] args)
{
string data;
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 5566);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(ipEnd);
socket.Listen(10);
Console.WriteLine("Waiting for a client");
Socket client = socket.Accept();
IPEndPoint ipEndClient = (IPEndPoint)client.RemoteEndPoint;
Console.WriteLine("Connect with {0} at port {1}", ipEndClient.Address, ipEndClient.Port);
NetworkStream ns = new NetworkStream(client);
StreamReader sr = new StreamReader(ns);
StreamWriter sw = new StreamWriter(ns);
string welcome = "Welcome to my server";
sw.WriteLine(welcome);
sw.Flush();
while (true)
{
try
{
data = sr.ReadLine();
}
catch (IOException)
{
break;
}
Console.WriteLine(data);
sw.WriteLine(data);
sw.Flush();
}
Console.WriteLine("Disconnect form {0}", ipEndClient.Address);
sw.Close();
sr.Close();
ns.Close();
}
{
string data;
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 5566);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(ipEnd);
socket.Listen(10);
Console.WriteLine("Waiting for a client");
Socket client = socket.Accept();
IPEndPoint ipEndClient = (IPEndPoint)client.RemoteEndPoint;
Console.WriteLine("Connect with {0} at port {1}", ipEndClient.Address, ipEndClient.Port);
NetworkStream ns = new NetworkStream(client);
StreamReader sr = new StreamReader(ns);
StreamWriter sw = new StreamWriter(ns);
string welcome = "Welcome to my server";
sw.WriteLine(welcome);
sw.Flush();
while (true)
{
try
{
data = sr.ReadLine();
}
catch (IOException)
{
break;
}
Console.WriteLine(data);
sw.WriteLine(data);
sw.Flush();
}
Console.WriteLine("Disconnect form {0}", ipEndClient.Address);
sw.Close();
sr.Close();
ns.Close();
}