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

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

原理:

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.服务器

主函数:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServerTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // 调用构造函数,使用Start方法
            ServerControl server = new ServerControl();
            server.Start();

            Console.ReadKey();
        }
    }
}

ServerControl类:

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 ServerTest
{
    public class ServerControl
    {
        // 声明变量(使用Socket需using System.Net.Sockets;)
        private Socket serverSocket;

        // 自定义有参构造方法(IP地址,流程传输方式,TCP协议)
        public ServerControl()
        {
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        // 创建启动方法(IPEndPoint用于指定地址及端口初始化,需using System.Net;)
        public void Start()
        {
            // 服务器启动
            // 绑定IP地址(为任意IP)与端口(设置为12345)
            serverSocket.Bind(new IPEndPoint(IPAddress.Any,12345));
            serverSocket.Listen(10);
            Console.WriteLine("服务器启动成功");

            // 开启线程:目的实现服务器和客户端一对多连接
            Thread threadAccept = new Thread(Accept);
            threadAccept.IsBackground = true;
            threadAccept.Start();
        }
         // Accept方法测试:接收客户端连接
        private void Accept()
        {
            // 接收客户端方法,会挂起当前线程(.RemoteEndPoint表示远程地址)
            Socket client = serverSocket.Accept();
            IPEndPoint point = client.RemoteEndPoint as IPEndPoint;
            Console.WriteLine(point.Address + "[" + point.Port + "] 连接成功!");

            // 开启一个新线程线程,实现消息多次接收
            Thread threadReceive = new Thread(Receive);
            threadReceive.IsBackground = true;
            threadReceive.Start(client);

            // 尾递归
            Accept();
        }

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

            IPEndPoint point = client.RemoteEndPoint as IPEndPoint;

            // 此处的异常抛出主要针对客户端异常的问题
            // 比如,客户端关闭或者连接中断
            // 程序会停留在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可实现不同计算机之间的连接。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ClientTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // 调用构造函数
            ClientControl client = new ClientControl();
            // 输入本机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类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ClientTest
{
    public class ClientControl
    {
        // 声明变量
        private Socket clientSocket;

        // 自定义有参构造方法((IP地址,流程传输方式,TCP协议))
        public ClientControl()
        {
            clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        }

        // 创建通过IP与端口号连接的方法
        public void Connect(string ip,int port)
        {
            clientSocket.Connect(ip, port);
            Console.WriteLine("连接服务器成功");

            // 客户端接收服务器消息的线程
            Thread threadReceive = new Thread(Receive);
            threadReceive.IsBackground = true;
            threadReceive.Start();
        }

        // 用于测试服务器向客户端返回一条消息
        private void Receive()
        {
            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(string msg)
        {
            // 将字符创传化为字节数组
            clientSocket.Send(Encoding.UTF8.GetBytes(msg));
        }
    }
}

4.实现

本地连接:IP为127.0.0.1

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

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

2.使用远程桌面连接

3.连接成功

原文地址:https://www.cnblogs.com/WeiMLing/p/11324133.html

时间: 2024-10-29 19:09:58

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

一个基于TCP/IP的小项目,实现广播消息的功能。(超详细版)

1.结合现状 功能分析 该功能基于上个项目的改进,主要是通过对服务器端代码的修改,以及对客户端作少许修改,实现开启多客户端时,一个客户端发送消息,达到对所有客户端广播的效果.可参考网吧里的点歌系统,比如某某用户在网吧点了一首歌,其他用户电脑的左下角都会弹出一个某某用户点了一首七里香,或者游戏里面的频道聊天,每个人发完消息后,聊天室里的人都知道你发的消息了,就像下图一样,这也正是做这个功能的初衷吧. 2.图说代码 代码细说: 服务器里面定义了两个字段,一个用于服务器与客户端的连接,另一个目的在于做

java socket 基于TCP/IP 协议

Java socket 基于TCP/IP 协议应用 多线程服务器原理: 1.          服务器端创建serversocket并绑定要监听的端口号 ,循环调用serversoket 的accept()方法,等待客户端的连接请求 2.          客户端创建一个socket绑定服务器端的IP地址和服务器监听的端口号并请求和服务器端连接 3.          服务器端接收到客户端的请求后,创建一个socket与客户端建立专线连接 4.          建立连接的两个socket在一个

基于TCP协议的服务器中转简易聊天

项目比较简单:主要使用了TCP传输协议.多线程和swing窗口,以及IO流读写. 功能:各窗口之间简单的收发信息,另外附加一个抖动的效果. 服务器代码: 1 package com.java; 2 3 import java.awt.Dimension; 4 import java.awt.Toolkit; 5 import java.awt.event.ActionEvent; 6 import java.awt.event.ActionListener; 7 import java.awt.

JAVA Socket 底层是怎样基于TCP/IP 实现的???

首先必须明确:TCP/IP模型中有四层结构:       应用层(Application Layer).传输层(Transport  Layer).网络层(Internet Layer  ).链路层(LinkLayer)  其中Ip协议(Internet Protocol)是位于网络层的,TCP协议时位于传输层的.通过Ip协议可以使可以使两台计算机使用同一种语言,从而允许Internet上连接不同类型的计算机和不同操作系统的网络.Ip协议只保证计算机能够接收和发送分组数据. 当计算机要和远程的计

网络编程TCP/IP与UDP实现客户端与客户端聊天

一.TCP/IP协议 既然是网络编程,涉及几个系统之间的交互,那么首先要考虑的是如何准确的定位到网络上的一台或几台主机,另一个是如何进行可靠高效的数据传输.这里就要使用到TCP/IP协议. TCP/IP协议(传输控制协议)由网络层的IP协议和传输层的TCP协议组成.IP层负责网络主机的定位,数据传输的路由,由IP地址可以唯一的确定Internet上的一台主机.TCP层负责面向应用的可靠的或非可靠的数据传输机制,这是网络编程的主要对象. 二.TCP与UDP TCP是一种面向连接的保证可靠传输的协议

基于 TCP/IP 协议的网络编程

在说明基于 TCP/IP 协议的网络编程之前,先来了解一下 Socket(网络套接字): 利用套接字(Socket)开发网络应用程序早已被广泛的采用,以至于成为事实上的标准 通信的两端都要有 Socket,是两台机器间通信的端点(API 原话) 网络通信其实就是 Socket 间的通信 Socket 允许程序把网络连接当成一个流,数据在两个 Socket 间通过 IO 传输 一般主动发起通信的应用程序属客户端,等待通信请求的为服务端 网络编程某种程度上可以称作"Socket 编程" T

基于TCP的安卓服务器开发

一.说明 前文介绍了基于安卓客户端的开发,在此基础上,进行少许改动即可开发出一款基于TCP的安卓服务器,理论知识请参见笔者上一篇博文,下面直接实践操作. 二.权限申明 1 <!--允许应用程序改变网络状态--> 2 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> 3 4 <!--允许应用程序改变WIFI连接状态--> 5 <uses-permis

SPWebServer:一个基于 SPServer 的 web 服务器框架

SPWebServer:一个基于 SPServer 的 web 服务器框架 博客分类: OpenSource项目 应用服务器框架Web网络应用多线程 看到这个题目,估计很多人会问:为什么要再实现一个 web 服务器? 这里有几个原因: 1.这是一个 web 服务器框架,不是一个完整的 web 服务器.也就是说 SPWebServer 提供的是一套 API 和类库,可以方便地集成到现有的应用程序中.可以称 SPWebServer 为 embedded web server . 2.有些时候,我们需

基于SignalR的服务端和客户端通讯处理

SignalR是一个.NET Core/.NET Framework的实时通讯的框架,一般应用在ASP.NET上,当然也可以应用在Winform上实现服务端和客户端的消息通讯,本篇随笔主要基于SignalR的构建一个基于Winform的服务端和客户端的通讯处理案例,介绍其中的处理过程. 1.SignalR基础知识 SignalR是一个.NET Core/.NET Framework的开源实时框架. SignalR的可使用Web Socket, Server Sent Events 和 Long