目标
- 用Socket完成服务器代码的编写,能够实现接收客户端的请求,并返回"I've received the msg."已完成
- 用Socket完成客户端代码的编写,能够实现向服务端发送请求。已完成
- 实现客户端、服务端双向通信(将服务端发送的内容,改成从界面获取就好了。这样就是一个点对点的了。 String s = Console.ReadLine();// 等待用户输入)。本节目标
- 简单放上我之前的关于线程的简单测试吧。线程基本
- 实现服务端响应多个客户端,加入了线程。本节目标
- 将Socket请求可以封装起来,后续就可以减少一些重复代码
- 实现聊天的功能
- 待开发。。。
准备工作
- Windows 10 2016 64位
- VS 2019
- using System.Text; Encoding
- using System.Net; IPAddress
- using System.Net.Sockets; Socket
- using System.Threading; Thread
带System的命名空间一般是vs自带的,只要你安装的时候选了,大多都会自带。
代码
服务端
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace MyServer
{
class Program
{
static void Main(string[] args)
{
try
{
// 1.使用http协议建立连接
Socket listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listen.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8899));
listen.Listen(3);// 从0开始计数,也就是可以连接4个客户端
Console.WriteLine("The server is listening...");
2.使用死循环持续接收客户端连接请求(我的连接请求限制是3个 listen.Listen(3);)
点对点不需要这个循环,因为接受来自客户端的请求也需要开辟新的线程去处理
/// 监听数最好限制在1个,因为没有开辟线程去处理吧
while (true)
{
Socket client = listen.Accept();
Console.WriteLine("the connection from {0}", client.RemoteEndPoint);
// 3.使用线程,在线程里死循环用socket协议进行持续通信(write,read;send,receive)
// 在做這一步之前,先了解一下線程是如何使用的 4 ways to create a thread
// 當然你直接照我下面那樣寫也是沒有問題的
// a. static method(靜態方法)
// b. instance(实例)
// c. delegate(委託)
// d. lambda(表達式)
// 使用线程
Thread thLambda = new Thread((object cc) =>
{
Socket thc = (Socket)cc;
while (true)
{
byte[] re = new byte[1024];
// 捕獲 客戶端強制關閉時引發的異常,讓程序能正常運行,不意外關閉
try
{
// 等待客戶端輸入
// 當客戶端斷開鏈接,此處會報錯:遠端主機[客戶端]已強制關閉一個現存的連線。
thc.Receive(re);//在这里等待客户端的输入,并将输入的内容存到 re 里
}
catch (Exception ex)
{
thc.Close();
Console.WriteLine("[{0}]{1}", client.RemoteEndPoint,ex.Message);
break;
}
Console.WriteLine("From client[{1}]:{0}", Encoding.UTF8.GetString(re), client.RemoteEndPoint);
// 固定发送数据
// 升级版本为指定发给某一客户端,需要存储连接进来的套接字,下个版本用窗体写吧。
thc.Send(Encoding.UTF8.GetBytes("I've received the message."));
}
});
thLambda.Start(client);
Console.WriteLine("The thread is start.");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
Console.WriteLine("Error{0}\r{1}", ex.Message, ex.StackTrace);
}
}
}
}
客户端
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace MyClient
{
class Program
{
/// <summary>
/// Socket 第一次建立连接(向服务器发起请求)的时候,使用的是http协议
/// 连接成功后,使用socket协议进行交流(双向交流,类似QQ)。
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
try
{
// 1.使用http协议建立连接
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8899));
if (client.Connected)
Console.WriteLine("You guys can chat now!");
// 2.使用死循环用socket协议进行持续通信(write,read;send,receive)
while (true)
{
String s = Console.ReadLine();// 等待用户输入
if (s == "bye")
break;
// 向服务器发送用户输入的数据
// 与服务器进行通信
int len = client.Send(Encoding.UTF8.GetBytes(s));
// 接收服务器返回的数据
byte[] re = new byte[1024];
int ire = client.Receive(re);
Console.WriteLine("Form server:{0}", Encoding.UTF8.GetString(re));
}
client.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
Console.WriteLine("Error....{0}\r{1}", ex.Message, ex.StackTrace);
}
Console.ReadLine();
}
}
}
效果