概述
C#Socket编程详解(一)TCP与UDP简介
https://blog.csdn.net/subin_iecas/article/details/80289513
C#Socket编程详解(二)单播、多播、广播
https://blog.csdn.net/subin_iecas/article/details/80289867
C#Socket编程详解(三)Socket编程
https://blog.csdn.net/subin_iecas/article/details/80289915
使用Socket编程实现聊天室
服务器端
服务端的主要职责是处理各个客户端发送来的数据,因此在客户端的Socket编程中需要使用两个线程来循环处理客户端的请求,一个线程用于监听客户端的连接情况,一个线程用于监听客户端的消息发送。
基本流程
1. 创建套接字
2. 绑定套接字的IP和端口号——Bind(EndPoint)
3. 将套接字处于监听状态等待客户端的连接请求——Listen(int) 监听端口,其中parameters表示最大监听数。
4. 阻塞方法,当请求到来后,接受请求并返回本次会话的套接字——Accept()接受客户端链接,并返回一个新的链接,用于处理同客户端的通信问题。
5. 使用返回的套接字和客户端通信——Send()/Receive()
Send(byte[]) 简单发送数据。
Send(byte[],SocketFlag) 使用指定的SocketFlag发送数据。
Send(byte[],int, SocketFlag) 使用指定的SocketFlag发送指定长度数据。
Send(byte[], int, int,SocketFlag) 使用指定的SocketFlag,将指定字节数的数据发送到已连接的socket(从指定偏移量开始)。
Receive(byte[]) 简单接受数据。
Receive(byte[],SocketFlag) 使用指定的SocketFlag接受数据。
Receive(byte[], int, SocketFlag) 使用指定的SocketFlag接受指定长度数据。
Receive (byte[], int,int, SocketFlag) 使用指定的SocketFlag,从绑定的套接字接收指定字节数的数据,并存到指定偏移量位置的缓冲区。
6. 返回,再次等待新的连接请求
7. 关闭套接字
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace socket聊天室服务端
{
class Program
{
static List<Client> clientList = new List<Client>();
//广播消息
public static void BroadCastMessage(string message) {
var notConnectedList = new List<Client>();//存放所有断开连接的client
foreach (var client in clientList)
{
if (client.Connected)
{
client.SendMessage(message);
}
else
{
notConnectedList.Add(client);
}
}
//移除所有的断开连接的client
foreach (var temp in notConnectedList)
{
clientList.Remove(temp);
}
}
static void Main(string[] args)
{
//创建Socket
Socket tcpServer = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//得到本机IP,设置TCP端口号
tcpServer.Bind(new IPEndPoint(IPAddress.Parse("192.168.1.102"),7788));
//开始监听
tcpServer.Listen(100);
Console.WriteLine("server running");
while (true)
{
//等待客户端连接
Socket clientSocket = tcpServer.Accept();
Console.WriteLine("a client is connect!");
//创建Client类与客户端做连接
//把与每个客户端通信的逻辑(收发信息)放到Client类里面进行处理
Client client = new Client(clientSocket);
clientList.Add(client);
}
}
}
}
Client类用来与客户端做通信
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace socket聊天室服务端
{/// <summary>
/// 用来与客户端做通信
/// </summary>
class Client
{
private Socket clientSocket;
private Thread t;
private byte[] data = new byte[1024];//数据容器
public Client(Socket s) {
clientSocket = s;
//启动一个线程处理客户端的数据接收
t = new Thread(ReceiveMessage);
t.Start();
}
private void ReceiveMessage() {
//循环一直接收客户端数据
while (true)
{
//在接收数据之前,判断Socket是否仍能读取数据,返回false说明断开了连接
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);
}
//判断socket是否连接中
public bool Connected {
get { return clientSocket.Connected; }
}
}
}
客户端Unity
客户端相对于服务端来说任务要轻许多,因为客户端仅仅需要和服务端通信即可,可是因为在和服务器通信的过程中,需要时刻保持连接通畅,因此同样需要两个线程来分别处理连接情况的监听和消息发送的监听。
基本流程
1. 创建套接字保证与服务器的端口一致
2. 向服务器发出连接请求——Connect(EndPoint)连接远程服务器,如果没有相应的远程等待连接,直接返回错误。
3. 和服务器端进行通信——Send()/Receive()
4. 关闭套接字
UI
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
using UnityEngine.UI;
public class ChatManager : MonoBehaviour {
public string ip="192.168.1.102" ;//IP地址
public int port = 7788;//端口号
private Socket clientSocket;
private Thread t;
private byte[] data = new byte[1024];//接收服务器广播消息容器
public InputField inputField;
public InputField outText;
private string message="";//消息容器
void Start () {
//创建Socket,建立连接
ConnectToServer();
}
// Update is called once per frame
void Update () {
if (message!=null&&message!="")
{
outText.text += message+"n";
message = "";//清空消息
}
}
void ConnectToServer() {
//创建Socket
clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//跟服务器建立连接
IPAddress ipaddress = IPAddress.Parse(ip);
clientSocket.Connect(new IPEndPoint(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);
//outText.text += "n" + message;
}
}
//发送数据
public void OnSendButtonClick()
{
string value = inputField.text;
SendMessage(value);
inputField.text = "";
}
void SendMessage(string message) {
//先将字符串转化为byte数组
byte[] data = Encoding.UTF8.GetBytes(message);
clientSocket.Send(data);
}
private void OnDestroy()
{
clientSocket.Shutdown(SocketShutdown.Both);//接收和发送都关闭
clientSocket.Close();//关闭连接
}
}
最后
以上就是矮小夕阳为你收集整理的Socket编程的全部内容,希望文章能够帮你解决Socket编程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复