小项目服务器,一个基于TCP/IP的服务器与客户端通讯的小项目(超详细版)

1.目的:实现客户端向服务器发送数据

原理:

446c35a4e8159c2750283161315ffe91.png

2.建立两个控制台应用,一个为服务器,用于接收数据。一个为客户端,用于发送数据。

关键类与对应方法:

1)类IPEndPoint:

1.是抽象类EndPoint的实现类

2.Socket对象的RemoteEndPoint、 LocalEndPoint都是这个类型

3.属性Address: 使用IPv4表示的地址

4.属性Port:使用int表示的端口

2)类Socket:

这个类即可以用于作服务器端的开发,又可以作客户端的开发

构造方法:

参数 AddressFamily:指定使用IPv4的地址InterNetwork

参数SocketType:指定使用流式传输Stream

参数ProtocolType:指定协议类型Tcp

1.方法Bind()E 绑定IP与端口,这样就成为了服务器,可以监听指定IP的特定端口

2.方法Listen(); 置于监听状态,参数是最大的挂起数

3.方法Accept(): 接收客户端连接,返回Socket对象, 这个方法会阻塞当前线程,建议开启新线程执行些方法,结合尾递归,这样就可以接收多个客户端

4.方法Receive(): 接收客户端发送过来的消息,以字节为单位进行操作,此方法会阻塞当前线程,建议开启新线程执行此方法,结合尾递归,就可以持续接收多条信息

5. 方法Send(): 发送消息,以字节为单位

3.具体实现

其他内容不做过多解释了,备注做的超详细,应该只有笨笨的人才写这么多备注吧。。

1.服务器

主函数:

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceServerTest

{classProgram

{static void Main(string[] args)

{//调用构造函数,使用Start方法

ServerControl server = newServerControl();

server.Start();

Console.ReadKey();

}

}

}

ServerControl类:

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading;usingSystem.Threading.Tasks;namespaceServerTest

{public classServerControl

{//声明变量(使用Socket需using System.Net.Sockets;)

privateSocket serverSocket;//自定义有参构造方法(IP地址,流程传输方式,TCP协议)

publicServerControl()

{

serverSocket= newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

}//创建启动方法(IPEndPoint用于指定地址及端口初始化,需using System.Net;)

public voidStart()

{//服务器启动//绑定IP地址(为任意IP)与端口(设置为12345)

serverSocket.Bind(new IPEndPoint(IPAddress.Any,12345));

serverSocket.Listen(10);

Console.WriteLine("服务器启动成功");//开启线程:目的实现服务器和客户端一对多连接

Thread threadAccept = newThread(Accept);

threadAccept.IsBackground= true;

threadAccept.Start();

}//Accept方法测试:接收客户端连接

private voidAccept()

{//接收客户端方法,会挂起当前线程(.RemoteEndPoint表示远程地址)

Socket client =serverSocket.Accept();

IPEndPoint point= client.RemoteEndPoint asIPEndPoint;

Console.WriteLine(point.Address+ "[" + point.Port + "] 连接成功!");//开启一个新线程线程,实现消息多次接收

Thread threadReceive = newThread(Receive);

threadReceive.IsBackground= true;

threadReceive.Start(client);//尾递归

Accept();

}//Receive方法的使用测试//接收客户端发送过来的消息,以字节为单位进行操作//该方法会阻塞当前线程,所以适合开启新的线程使用该方法//Accept()中将Receive作为线程传递对象,所以要注意一点,使用线程传递对象只能是object类型的!!

private void Receive(objectobj)

{//将object类型强行转换成socket

Socket client = obj asSocket;

IPEndPoint point= client.RemoteEndPoint asIPEndPoint;//此处的异常抛出主要针对客户端异常的问题//比如,客户端关闭或者连接中断//程序会停留在int msgLen = client.Receive(msg);这段代码,而导致无法继续往下走

try{byte[] msg = new byte[1024];//实际接收到字节数组长度,该方法会阻塞当前线程,即(client.Receive(msg)开始挂起)//同时,这里还是尾递归挂起处

int msgLen =client.Receive(msg);//将msg装换成字符串

Console.WriteLine(point.Address + "[" + point.Port + "]:" + Encoding.UTF8.GetString(msg, 0, msgLen));//此处实现服务器自动向客户端返回一条消息//因为Send发送信息是以字节为单位发送的//所以下面(Encoding.UTF8.GetString(msg,0,msgLen)+" yes.boy")这一块是把这一部分均搞成string//后使用Encoding.UTF8.GetBytes统一转化成字节传递//这里呢,已经实现服务器向客户端发送消息了,客户端只需要receive一下,格式一转就可视化了

client.Send(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(msg,0,msgLen)+"yes.boy"));//尾递归实现多条消息的接收;和while同理。

Receive(client);

}catch{

Console.WriteLine(point.Address+ "[" + point.Port + "]积极断开");

}

}

}

}

2.客户端:

主函数:

client.Connect("127.0.0.1",12345);

修改IP可实现不同计算机之间的连接。

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceClientTest

{classProgram

{static void Main(string[] args)

{//调用构造函数

ClientControl client = newClientControl();//输入本机IP与端口号

client.Connect("127.0.0.1",12345);//提示操作方法

Console.WriteLine("请输入发送至服务器的内容或者输入quit退出");//输入内容

string msg =Console.ReadLine();//非退出情况下操作方式,使用while可以持续不断的接收用户输入

while(msg != "quit")

{

client.Send(msg);

msg=Console.ReadLine();

}

Console.ReadKey();

}

}

}

ClientControl类:

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading;usingSystem.Threading.Tasks;namespaceClientTest

{public classClientControl

{//声明变量

privateSocket clientSocket;//自定义有参构造方法((IP地址,流程传输方式,TCP协议))

publicClientControl()

{

clientSocket= newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

}//创建通过IP与端口号连接的方法

public void Connect(string ip,intport)

{

clientSocket.Connect(ip, port);

Console.WriteLine("连接服务器成功");//客户端接收服务器消息的线程

Thread threadReceive = newThread(Receive);

threadReceive.IsBackground= true;

threadReceive.Start();

}//用于测试服务器向客户端返回一条消息

private voidReceive()

{while(true)

{try{//用于接收服务器的回复信息

byte[] msg = new byte[1024];int msgLen =clientSocket.Receive(msg);

Console.WriteLine("服务器:"+Encoding.UTF8.GetString(msg,0,msgLen));

}//异常处理方法

catch{

Console.WriteLine("服务器积极拒绝!!");//退出while循环

break;

}

}

}//Send方法测试:即发送消息,以字节为单位

public void Send(stringmsg)

{//将字符创传化为字节数组

clientSocket.Send(Encoding.UTF8.GetBytes(msg));

}

}

}

4.实现

本地连接:IP为127.0.0.1

236a2fecee212958cef631ef5c4604bb.png

远程连接:因为我只有一台电脑,所以用腾讯云服务器作为我的服务器,我本地的PC作为客户端,实现连接。

1.修改客户端主程序里面的IP为我的腾讯云IP

86217c38b0bb78876a25026af77e8c63.png

2.使用远程桌面连接

15755d0cca2a5d557fb6a9e4bfa7d834.png

3.连接成功

506173104124580c5387dba3fab08f6f.png

原文出处:https://www.cnblogs.com/WeiMLing/p/11324133.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值