C# Socket Programming Practice 1
Target
- Use Socket to complete the writing of the server code, which can receive the client's request and return "I've received the msg." Completed
- Use Socket to complete the writing of client code, which can send requests to the server. completed
- Realize two-way communication between client and server (just change the content sent by the server to obtain it from the interface. This is point-to-point. String s = Console.ReadLine(); // Wait for user input). Goal of this section
- Let’s simply put my previous simple test about threads. thread basic
- The server is implemented to respond to multiple clients and threads are added. Objectives of this section
- Socket requests can be encapsulated, which can reduce some repeated code in the future.
- Implement chat function
- To be developed. . .
Preparation
- Windows 10 2016 64 bit
- VS 2019
- using System.Text; Encoding
- using System.Net; IPAddress
- using System.Net.Sockets; Socket
- using System.Threading; Thread
The namespace with System usually comes with VS. As long as you select it during installation, most of them will come with it.
code
Server
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);
}
}
}
}
client
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();
}
}
}
Effect