一个简单的服务器端和客户端程序
服务器端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace _026_socket编程_TCP协议
{
class Program
{
static void Main(string[] args)
{
//1.创建socket
Socket tcpServer = new Socket
(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//对应属性分别是内网,流数据以及Tcp协议
//2.绑定ip和端口号 172.16.1.102
IPAddress ipaddress = new IPAddress(new byte[] {172,16,1,102});//获取ip地址
EndPoint point = new IPEndPoint(ipaddress,7788);//IPEndPoint是对ip+端口做了一次封装的类
tcpServer.Bind(point);//向操作系统申请一个可用的ip跟端口号 用来做通信
//3.开始监听(等待客户端连接)
tcpServer.Listen(100);//参数是最大连接数
Console.WriteLine("开始监听");
Socket clientSocket = tcpServer.Accept();//暂停当前线程,直到有一个客户端连接过来,之后进行下面的代码
//使用返回的socket跟客户端做通信
Console.WriteLine("一个客户端连接过来了");
string message = "hello 欢迎你";
byte[] data = Encoding.UTF8.GetBytes(message);//对字符串做编码,得到一个字符串的字节数组
clientSocket.Send(data);
Console.WriteLine("向客户端发送了一条数据");
byte[] data2 = new byte[1024];//创建一个字节数组用来当做容器,去承接客户端发送过来的数据
int length = clientSocket.Receive(data2);
string message2 = Encoding.UTF8.GetString(data2, 0, length);//把字节数据转换成一个字符串
Console.WriteLine("接收到了一个从客户端发送来的消息:" + message2);
Console.ReadKey();
}
}
}
客户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace _001_socket编程_tcp协议_客户端
{
class Program
{
static void Main(string[] args)
{
//1.创建socket
Socket tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//2.发起建立连接的请求
IPAddress ipaddress = IPAddress.Parse("172.16.1.102");//可以把一个字符串的IP地址转化成一个ipaddress的
//对象
EndPoint point = new IPEndPoint(ipaddress,7788);
tcpClient.Connect(point);//通过ip:端口号 定位一个要连接到的服务器端
byte[] data = new byte[1024];
int length = tcpClient.Receive(data);//这里传递一个byte数组,实际上这个data数组用来接收数据
//length返回值表示接收了多少字节的数据
string message = Encoding.UTF8.GetString(data,0,length);//只把接收到的数据做一个转化
Console.WriteLine(message);
//向服务器端发送消息
string message2 = Console.ReadLine();//读取用户的输入 把输入发送到服务器端
tcpClient.Send(Encoding.UTF8.GetBytes(message2));//把字符串转化成字节数组,然后发送到服务器端
Console.ReadKey();
}
}
}
服务器端结果
客户端结果
聊天室_socket_tcp服务器端
Client.cs用来和客户端做通信,处理客户端来的消息
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace _027_聊天室_socket_tcp服务器端
{
//用来和客户端做通信
class Client
{
private Socket clientSocket;
private Thread t;
private byte[] data = new byte[1024];//数据容器
public Client(Socket s)
{
clientSocket = s;
//启动一个线程 处理客户端的数据接收
Thread t = new Thread(ReceiveMessage);
t.Start();
}
private void ReceiveMessage()
{
//一直接收客户端的数据
while (true)
{
//在接收数据之前 判断一下socket链接是否断开
if(clientSocket.Poll(10, SelectMode.SelectRead))
{
clientSocket.Close();
break;//跳出循环 终止线程的执行
}
int length = clientSocket.Receive(data);
string message = Encoding.UTF8.GetString(data, 0, length);
//接收到数据的时候, 要把这个数据分发到客户端
//广播这个消息
Program.BroadcastMessage(message);
Console.WriteLine("收到了消息:" + message);
}
}
public void SendMessage(string message)
{
byte[] data = Encoding.UTF8.GetBytes(message);
clientSocket.Send(data);
}
public bool Connected
{
get
{
return clientSocket.Connected;
}
}
}
}
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace _027_聊天室_socket_tcp服务器端
{
class Program
{
static List<Client> clientList = new List<Client>();
//广播消息
public static void BroadcastMessage(string message)
{
var notConnectedList = new List<Client>();
foreach (var client in clientList)
{
if(client.Connected)
client.SendMessage(message);
else
{
notConnectedList.Add(client);
}
}
foreach(var temp in notConnectedList)
{
clientList.Remove(temp);
}
}
static void Main(string[] args)
{
Socket tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
tcpServer.Bind(new IPEndPoint(IPAddress.Parse("192.168.184.1"), 7788));
tcpServer.Listen(100);
Console.WriteLine("Server running...");
while (true)
{
Socket clientSocket = tcpServer.Accept();
Console.WriteLine("a client is connected!");
Client client = new Client(clientSocket);//把与每个客户端通信的逻辑(收发消息)
//放到client对象里面进行处理
clientList.Add(client);
}
}
}
}
客户端使用unity,界面如下:
核心代码:
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
public class ChatManager : MonoBehaviour {
public string ipaddress = "192.168.184.1";
public int port = 7788;
public UIInput textInput;
public UILabel chatLabel;
private Socket clientSocket;
private Thread t;
private byte[] data = new byte[1024];//数据容器
private string message = "";//消息容器
// Use this for initialization
void Start () {
ConnectToServer();
}
// Update is called once per frame
void Update () {
if (message != null && message != "")
{
chatLabel.text += "\n" + message;
message = "";//清空消息
}
}
void ConnectToServer()
{
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//跟服务器端建立连接
clientSocket.Connect(new IPEndPoint(IPAddress.Parse(ipaddress), port));
//创建一个新的线程 用来接收消息
t = new Thread(ReceiveMessage);
t.Start();
}
//这个线程方法用来循环接收方法
void ReceiveMessage()
{
while (true)
{
if (clientSocket.Connected == false)
break;
int length = clientSocket.Receive(data);
message = Encoding.UTF8.GetString(data, 0, length);
//chatLabel.text += "\n" + message;
}
}
void SendMessage(string message)
{
byte[] data = Encoding.UTF8.GetBytes(message);
clientSocket.Send(data);
}
public void OnSendButtonClick()
{
string value = textInput.value;
SendMessage(value);
textInput.value = "";
}
void OnDestroy()
{
clientSocket.Shutdown(SocketShutdown.Both);//关闭:既不接受,也不发送
clientSocket.Close();//关闭链接
}
}
结果展示如下:
UDP协议网络编程
服务器端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace _028_socket编程_UDP协议_服务器端
{
class Program
{
static Socket udpServer;
static void Main(string[] args)
{
udpServer = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
udpServer.Bind(new IPEndPoint(IPAddress.Parse("172.16.1.102"), 7788));
new Thread(ReceiveMessage) {IsBackground = true }.Start();
//udpServer.Close();
Console.ReadKey();
}
static void ReceiveMessage()
{
//接收数据
while (true)
{
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] data = new byte[1024];
int length = udpServer.ReceiveFrom(data, ref remoteEndPoint);//这个方法会把数据的来源(ip:port)放到第二个参数上
string message = Encoding.UTF8.GetString(data, 0, length);
Console.WriteLine("从ip:" + (remoteEndPoint as IPEndPoint).Address.ToString() + ":" +
(remoteEndPoint as IPEndPoint).Port + "收到了数据:" + message);
}
}
}
}
客户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace _002_socket编程_udp协议_客户端
{
class Program
{
static void Main(string[] args)
{
//创建socket
Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//发送数据
while (true)
{
EndPoint serverPoint = new IPEndPoint(IPAddress.Parse("172.16.1.102"), 7788);
string message = Console.ReadLine();
byte[] data = Encoding.UTF8.GetBytes(message);
udpClient.SendTo(data, serverPoint);
}
Console.ReadKey();
}
}
}
TCP与UDP的区别:
1.基于连接与无连接;
2.对系统资源的要求(TCP较多,UDP少);
3.UDP程序结构较简单;
4.流模式与数据报模式 ;
5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。
TcpListener和TcpClient:两个封装类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace _029_tcplistener
{
class Program
{
static void Main(string[] args)
{
//1.TcpListener对socket进行了封装,这个类里面自己会去创建socket对象
TcpListener listener = new TcpListener(IPAddress.Parse("172.16.1.102"),7788);
//2.开始进行监听
listener.Start();//开始进行监听
//3.等待客户端连接过来
TcpClient client = listener.AcceptTcpClient();
//4.取得客户端发送过来的数据
NetworkStream stream = client.GetStream();//得到了一个网络流 从这个网络流可以取得客户端发送过来的数据
while (true)
{
byte[] data = new byte[1024];//创建一个数据容器,用来承接数据
int length = stream.Read(data, 0, 1024);//读取数据
//0表示从数组的哪个索引开始存放数据
//1024表示最大读取的字节数
string message = Encoding.UTF8.GetString(data, 0, length);
Console.WriteLine("收到了消息:" + message);
}
stream.Close();
client.Close();
listener.Stop();
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace tcpclient
{
class Program
{
static void Main(string[] args)
{
//当我们创建tcpclient对象的时候,就会跟server去建立连接
TcpClient client = new TcpClient("172.16.1.102",7788);
NetworkStream stream = client.GetStream();
//read用来读写数据,write用来写入数据就是发送数据
while (true)
{
string message = Console.ReadLine();
byte[] data = Encoding.UTF8.GetBytes(message);
stream.Write(data, 0, data.Length);
}
stream.Close();
client.Close();
Console.ReadKey();
}
}
}
UdpClient
服务器端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace _030_UdpClient
{
class Program
{
static void Main(string[] args)
{
//创建udpclient 绑定ip跟端口号
UdpClient udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse("172.16.1.102"),7788));
//接收数据
IPEndPoint point = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
byte[] data = udpClient.Receive(ref point);//确定point确定数据来自哪个IP的哪个端口号,返回的是一个字节数组,就是我们的数据
string message = Encoding.UTF8.GetString(data);
Console.WriteLine("收到了消息:" + message);
}
udpClient.Close();
Console.ReadKey();
}
}
}
客户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace _004_udpclient
{
class Program
{
static void Main(string[] args)
{
//创建udpclient对象
UdpClient client = new UdpClient();
while (true)
{
string message = Console.ReadLine();
byte[] data = Encoding.UTF8.GetBytes(message);
client.Send(data, data.Length, new IPEndPoint(IPAddress.Parse("172.16.1.102"), 7788));
}
client.Close();
Console.ReadKey();
}
}
}
结果