C# 多线程阻塞式,网络服务器与客户端(一)
服务器端代码:
实测在阿里云服务器上,无论是先定义好外网IP,还是抓取的外网ip都无法成功监听(本地私网ip也不行)
在使用公网ip时,报错代码上有提及权限问题,推测是跟服务器安全组策略有关(权限问题),
因为在服务器管理页面,在开放端口时,用的也是根权限(0.0.0.0),其他类型的未测试。
猜测直接使用SSH连接服务器,使用Linux命令,关闭防火墙或手动开放端口,也能有类似的效果。
点击查看服务器端代码
using System;
//using System.Management;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Code = System.Text.Encoding;
namespace 服务器1
{
class Program
{
static List<Socket> socketList = new List<Socket>();
static void Main(string[] args)
{
//string ip = GetLocalIp();
//string publicIp= GetPublicServerIp.GetIP().ToString();
//Console.WriteLine("publicIp=>" + publicIp);
Socket tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//tcpSocket.Bind(new IPEndPoint(IPAddress.Parse(publicIp), 49898));
//服务器上直接用0.0.0.0即可,否则会报错,即使用的是正确的公网ip
tcpSocket.Bind(new IPEndPoint(IPAddress.Parse("0.0.0.0"), 49898));
//tcpSocket.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.xxx"), 9898));
tcpSocket.Listen(10);
Console.WriteLine("开始监听");
//接收客户端连接
new Thread(() =>
{
while (true)
{
Socket clientSocket = tcpSocket.Accept();
socketList.Add(clientSocket);
Console.WriteLine(clientSocket.RemoteEndPoint + "连接成功!!!现在还有{0}个连接", socketList.Count);
new Thread(() =>
{
try
{
if (clientSocket != null && clientSocket.Connected)
{
while (true)
{
byte[] buffer = new byte[1024];
int length = clientSocket.Receive(buffer);
string str = Code.UTF8.GetString(buffer, 0, length);
SendToAllClient(str, clientSocket);
}
}
}
catch (SocketException)
{
if (!clientSocket.Connected)
{
socketList.Remove(clientSocket);
Console.WriteLine("客户端{0}已断开连接,现在还有{1}个连接",clientSocket.RemoteEndPoint,socketList.Count);
}
//Console.WriteLine("SocketException"+ socketList.Count);
//Console.WriteLine(socketList.Count);
}
}).Start();
}
}).Start();
Console.ReadKey();
}
/// <summary>
/// 获取本地局域网ip
/// </summary>
/// <returns></returns>
private static string GetLocalIp()
{
IPAddress[] ipArray = Dns.GetHostAddresses(Dns.GetHostName());
string ip = "";
for (int i = 0; i < ipArray.Length; i++)
{
if (ipArray[i].AddressFamily.ToString() == "InterNetwork")
{
//if (i == ipArray.Length - 1)
//{
ip = ipArray[i].ToString();
Console.WriteLine("V4=>" + ipArray[i]);
//}
}
else
{
Console.WriteLine("其他=>" + ipArray[i]);
}
}
return ip;
}
/// <summary>
/// 转发给全部客户端
/// </summary>
/// <param name="buffer"></param>
/// <param name="clientSocket"></param>
private static void SendToAllClient(string str, Socket self)
{
byte[] buffer = Code.UTF8.GetBytes(str);
for (int i = 0; i < socketList.Count; i++)
{
if (socketList[i] == self) continue;
socketList[i].Send(buffer);
}
}
}
}
获取本地公网ip代码
点击查看GetPublicServerIp代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace 服务器1
{
class GetPublicServerIp
{
/// <summary>
/// 获取外网IP
/// </summary>
/// <returns></returns>
public static string GetIP()
{
using (var webClient = new WebClient())
{
try
{
webClient.Credentials = CredentialCache.DefaultCredentials;
byte[] pageDate = webClient.DownloadData("http://pv.sohu.com/cityjson?ie=utf-8");
string ip = Encoding.UTF8.GetString(pageDate);
webClient.Dispose();
Match rebool = Regex.Match(ip, @"\d{2,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}");
return rebool.Value;
}
catch (Exception )
{
return "";
}
}
}
}
}
客户端代码
在客户端代码上,要连接上服务器端,则需要正确的公网ip。
或者连接的是局域网,则需要正确的局域网ip,即本机ip。
查看本机ip可通过打开cmd,输入ipconfig命令查看,服务器上好像和这个命令有点差入。
点击查看客户端代码
using System;
using System.Net.Sockets;
using System.Threading;
using Code = System.Text.Encoding;
namespace 客户端1
{
class Program
{
static Socket clientSocket = null;
static void Main(string[] args)
{
clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//clientSocket.Connect("192.168.0.xxx", 9898);//局域网ip
clientSocket.Connect("xx.xxx.xxx.xx", 49898);//服务器公网ip
Console.WriteLine("连接成功!!!");
//接收信息
new Thread(()=> {
while (true)
{
byte[] buffer = new byte[1024];
int length = clientSocket.Receive(buffer);
string msg = Code.UTF8.GetString(buffer, 0, length);
Console.WriteLine(msg);
}
}).Start();
//发送信息
new Thread(()=> {
while (true)
{
string str = Console.ReadLine();
string msg = clientSocket.LocalEndPoint + ":" + str;
byte[] buffer = Code.UTF8.GetBytes(msg);
clientSocket.Send(buffer);
}
}).Start();
}
}
}
本文作者:飞飞吻
本文链接:https://www.cnblogs.com/flyingkisses/p/16021192.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步