使用C#搭建的Socket服务端以及安卓使用Socket连接服务端

本文介绍了如何使用C#搭建Socket服务端,并且阐述了选择Socket的原因,强调其便捷性。同时,文章说明了Socket的通信过程,并展示了服务端的桌面程序设计,包括用于显示连接客户端和消息的ListBox,以及启动和关闭服务的按钮。客户端部分提到了是Android应用,并因IP地址不固定而不便展示具体代码。
摘要由CSDN通过智能技术生成

大家好,奇葩安卓小白又来啦。这次写的是项目中用到的socket服务器。

上一篇讲到偷懒使用jtds连接数据库发现完全不能满足项目需要,因此只能苦逼的再打一个服务端。思前想后看了众多教程,终于决定使用socket搭服务器,为什么呢,因为方便啊!不用配置乱七八糟的文件什么,只要自己手动写点代码就可以了。至于为什么用C#来写,因为后天服务器的系统是Windows的,写一个Windows桌面程序比较方便。终究一个字,方便!

1.socket简介


Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

抽象来说,Socket实质上提供了进程通信的端点。进程通信之前,双方首先必须各自创建一个端点,否则是没有办法建立联系并相互通信的。正如打电话之前,双方必须各自拥有一台电话机一样。

这样说来,其实socket的两端本身并不存在服务端和客户端的区别,双方既可以是服务端也可以是客户端,因此可以避免自己搭建后台的麻烦,但是,在当前瘦客户端的需求下,谁还会把自己的设备当作服务端呢。

2.socket通信过程:

socket连接过程如图:(图片来自百度,侵删)


服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
3.上代码:

服务端:

桌面程序;两个listBox,一个显示所有连接的客户端,另一个显示客户端发送的消息,一个Textbox用于输入端口,两个button分别用于启动服务和关闭服务。


客户端是一个安卓的app,涉及到具体的项目就不展示了,由于本人用的是校园网,IP地址是不固定的,所以展示结果就比较麻烦,直接贴代码:

服务端:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace Server
{
    public partial class Form1 : Form
    {
        private static byte[] result = new byte[1024];

        static Socket serverSocket;
        private static Socket clientSocket;
        private List<Socket> allClientSocket = new List<Socket>();
        private List<string> allClientIp = new List<string>();//存储客户端IP
        private List<string> allClientId = new List<string>();//存储客户端发送的id,这是需要自己解析发送的消息的
        private List<Thread> allClientThread = new List<Thread>();//存储客户端线程

        private Thread myThread;//这个线程用来监听是否
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,下面是一个简单C# Socket服务端使用SocketAsyncEventArgs的示例代码: ```csharp using System; using System.Net; using System.Net.Sockets; using System.Threading; public class SocketServer { private Socket m_serverSocket; private Semaphore m_maxAcceptedClients; private SocketAsyncEventArgsPool m_readWritePool; public SocketServer(int maxConnections) { m_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); m_serverSocket.Bind(new IPEndPoint(IPAddress.Any, 1234)); m_serverSocket.Listen(maxConnections); m_maxAcceptedClients = new Semaphore(maxConnections, maxConnections); m_readWritePool = new SocketAsyncEventArgsPool(maxConnections); for (int i = 0; i < maxConnections; i++) { SocketAsyncEventArgs readEventArgs = new SocketAsyncEventArgs(); readEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed); readEventArgs.UserToken = new AsyncUserToken(); m_readWritePool.Push(readEventArgs); } } public void Start() { StartAccept(null); } private void StartAccept(SocketAsyncEventArgs acceptEventArgs) { if (acceptEventArgs == null) { acceptEventArgs = new SocketAsyncEventArgs(); acceptEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(Accept_Completed); } else { acceptEventArgs.AcceptSocket = null; } m_maxAcceptedClients.WaitOne(); if (!m_serverSocket.AcceptAsync(acceptEventArgs)) { ProcessAccept(acceptEventArgs); } } private void ProcessAccept(SocketAsyncEventArgs acceptEventArgs) { SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop(); AsyncUserToken userToken = (AsyncUserToken)readEventArgs.UserToken; userToken.Socket = acceptEventArgs.AcceptSocket; userToken.ReadEventArgs = readEventArgs; readEventArgs.AcceptSocket = userToken.Socket; if (!userToken.Socket.ReceiveAsync(readEventArgs)) { ProcessReceive(readEventArgs); } StartAccept(acceptEventArgs); } private void Accept_Completed(object sender, SocketAsyncEventArgs e) { ProcessAccept(e); } private void IO_Completed(object sender, SocketAsyncEventArgs e) { switch (e.LastOperation) { case SocketAsyncOperation.Receive: ProcessReceive(e); break; case SocketAsyncOperation.Send: ProcessSend(e); break; default: throw new ArgumentException("The last operation completed on the socket was not a receive or send"); } } private void ProcessReceive(SocketAsyncEventArgs e) { AsyncUserToken userToken = (AsyncUserToken)e.UserToken; if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { userToken.Data.AddRange(e.Buffer.Take(e.BytesTransferred)); if (userToken.Data.Count >= 4) { int len = BitConverter.ToInt32(userToken.Data.Take(4).ToArray(), 0); if (userToken.Data.Count >= 4 + len) { byte[] buffer = userToken.Data.Skip(4).Take(len).ToArray(); userToken.Data.RemoveRange(0, 4 + len); // 处理请求并响应 byte[] response = HandleRequest(buffer); Send(userToken.Socket, response); return; } } if (!userToken.Socket.ReceiveAsync(e)) { ProcessReceive(e); } } else { CloseClientSocket(userToken); } } private void ProcessSend(SocketAsyncEventArgs e) { AsyncUserToken userToken = (AsyncUserToken)e.UserToken; if (e.SocketError == SocketError.Success) { if (!userToken.Socket.ReceiveAsync(userToken.ReadEventArgs)) { ProcessReceive(userToken.ReadEventArgs); } } else { CloseClientSocket(userToken); } } private void Send(Socket socket, byte[] buffer) { SocketAsyncEventArgs sendEventArgs = new SocketAsyncEventArgs(); sendEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed); sendEventArgs.SetBuffer(buffer, 0, buffer.Length); sendEventArgs.UserToken = socket; if (!socket.SendAsync(sendEventArgs)) { ProcessSend(sendEventArgs); } } private void CloseClientSocket(AsyncUserToken userToken) { try { userToken.Socket.Shutdown(SocketShutdown.Send); } catch (Exception) { } userToken.Socket.Close(); m_readWritePool.Push(userToken.ReadEventArgs); m_maxAcceptedClients.Release(); } private byte[] HandleRequest(byte[] request) { // 处理请求并响应 return null; } } public class AsyncUserToken { public Socket Socket { get; set; } public List<byte> Data { get; set; } public SocketAsyncEventArgs ReadEventArgs { get; set; } public AsyncUserToken() { Data = new List<byte>(); } } ``` 以上示例代码演示了如何使用SocketAsyncEventArgs实现一个简单Socket服务端,其中包含了异步接收、异步发送和连接池等功能。当有客户端连接时,它会从连接池中获取一个SocketAsyncEventArgs对象,并使用它来进行通信。在通信完成后,它会将SocketAsyncEventArgs对象放回连接池中,以便于重用。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值