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

主函数:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace ServerTest
  8. {
  9. class Program
  10. {
  11. static void Main(string[] args)
  12. {
  13. // 调用构造函数,使用Start方法
  14. ServerControl server = new ServerControl();
  15. server.Start();
  16.  
  17. Console.ReadKey();
  18. }
  19. }
  20. }

ServerControl类:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Text;
  7. using System.Threading;
  8. using System.Threading.Tasks;
  9.  
  10. namespace ServerTest
  11. {
  12. public class ServerControl
  13. {
  14. // 声明变量(使用Socket需using System.Net.Sockets;)
  15. private Socket serverSocket;
  16.  
  17. // 自定义有参构造方法(IP地址,流程传输方式,TCP协议)
  18. public ServerControl()
  19. {
  20. serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  21. }
  22.  
  23. // 创建启动方法(IPEndPoint用于指定地址及端口初始化,需using System.Net;)
  24. public void Start()
  25. {
  26. // 服务器启动
  27. // 绑定IP地址(为任意IP)与端口(设置为12345)
  28. serverSocket.Bind(new IPEndPoint(IPAddress.Any,));
  29. serverSocket.Listen();
  30. Console.WriteLine("服务器启动成功");
  31.  
  32. // 开启线程:目的实现服务器和客户端一对多连接
  33. Thread threadAccept = new Thread(Accept);
  34. threadAccept.IsBackground = true;
  35. threadAccept.Start();
  36. }
  37. // Accept方法测试:接收客户端连接
  38. private void Accept()
  39. {
  40. // 接收客户端方法,会挂起当前线程(.RemoteEndPoint表示远程地址)
  41. Socket client = serverSocket.Accept();
  42. IPEndPoint point = client.RemoteEndPoint as IPEndPoint;
  43. Console.WriteLine(point.Address + "[" + point.Port + "] 连接成功!");
  44.  
  45. // 开启一个新线程线程,实现消息多次接收
  46. Thread threadReceive = new Thread(Receive);
  47. threadReceive.IsBackground = true;
  48. threadReceive.Start(client);
  49.  
  50. // 尾递归
  51. Accept();
  52. }
  53.  
  54. // Receive方法的使用测试
  55. // 接收客户端发送过来的消息,以字节为单位进行操作
  56. // 该方法会阻塞当前线程,所以适合开启新的线程使用该方法
  57. // Accept()中将Receive作为线程传递对象,所以要注意一点,使用线程传递对象只能是object类型的!!
  58. private void Receive(object obj)
  59. {
  60. // 将object类型强行转换成socket
  61. Socket client = obj as Socket;
  62.  
  63. IPEndPoint point = client.RemoteEndPoint as IPEndPoint;
  64.  
  65. // 此处的异常抛出主要针对客户端异常的问题
  66. // 比如,客户端关闭或者连接中断
  67. // 程序会停留在int msgLen = client.Receive(msg);这段代码,而导致无法继续往下走
  68. try
  69. {
  70. byte[] msg = new byte[];
  71. // 实际接收到字节数组长度,该方法会阻塞当前线程,即(client.Receive(msg)开始挂起)
  72. // 同时,这里还是尾递归挂起处
  73. int msgLen = client.Receive(msg);
  74. // 将msg装换成字符串
  75. Console.WriteLine(point.Address + "[" + point.Port + "]:" + Encoding.UTF8.GetString(msg, , msgLen));
  76. // 此处实现服务器自动向客户端返回一条消息
  77. // 因为Send发送信息是以字节为单位发送的
  78. // 所以下面(Encoding.UTF8.GetString(msg,0,msgLen)+" yes.boy")这一块是把这一部分均搞成string
  79. // 后使用Encoding.UTF8.GetBytes统一转化成字节传递
  80. // 这里呢,已经实现服务器向客户端发送消息了,客户端只需要receive一下,格式一转就可视化了
  81. client.Send(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(msg,,msgLen)+" yes.boy"));
  82. // 尾递归实现多条消息的接收;和while同理。
  83. Receive(client);
  84. }
  85. catch
  86. {
  87. Console.WriteLine(point.Address + "[" + point.Port + "]积极断开");
  88. }
  89. }
  90. }
  91. }

2.客户端:

主函数:

  1. client.Connect("127.0.0.1",12345);
    修改IP可实现不同计算机之间的连接。
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace ClientTest
  8. {
  9. class Program
  10. {
  11. static void Main(string[] args)
  12. {
  13. // 调用构造函数
  14. ClientControl client = new ClientControl();
  15. // 输入本机IP与端口号
  16. client.Connect("127.0.0.1",);
  17. // 提示操作方法
  18. Console.WriteLine("请输入发送至服务器的内容或者输入quit退出");
  19. // 输入内容
  20. string msg = Console.ReadLine();
  21. // 非退出情况下操作方式,使用while可以持续不断的接收用户输入
  22. while(msg != "quit")
  23. {
  24. client.Send(msg);
  25. msg = Console.ReadLine();
  26. }
  27.  
  28. Console.ReadKey();
  29. }
  30. }
  31. }

ClientControl类:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net.Sockets;
  5. using System.Text;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8.  
  9. namespace ClientTest
  10. {
  11. public class ClientControl
  12. {
  13. // 声明变量
  14. private Socket clientSocket;
  15.  
  16. // 自定义有参构造方法((IP地址,流程传输方式,TCP协议))
  17. public ClientControl()
  18. {
  19. clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
  20. }
  21.  
  22. // 创建通过IP与端口号连接的方法
  23. public void Connect(string ip,int port)
  24. {
  25. clientSocket.Connect(ip, port);
  26. Console.WriteLine("连接服务器成功");
  27.  
  28. // 客户端接收服务器消息的线程
  29. Thread threadReceive = new Thread(Receive);
  30. threadReceive.IsBackground = true;
  31. threadReceive.Start();
  32. }
  33.  
  34. // 用于测试服务器向客户端返回一条消息
  35. private void Receive()
  36. {
  37. while(true)
  38. {
  39. try
  40. {
  41. // 用于接收服务器的回复信息
  42. byte[] msg = new byte[];
  43. int msgLen = clientSocket.Receive(msg);
  44. Console.WriteLine("服务器:"+Encoding.UTF8.GetString(msg,,msgLen));
  45. }
  46. // 异常处理方法
  47. catch
  48. {
  49. Console.WriteLine("服务器积极拒绝!!");
  50. // 退出while循环
  51. break;
  52. }
  53. }
  54. }
  55.  
  56. // Send方法测试:即发送消息,以字节为单位
  57. public void Send(string msg)
  58. {
  59. // 将字符创传化为字节数组
  60. clientSocket.Send(Encoding.UTF8.GetBytes(msg));
  61. }
  62. }
  63. }

4.实现

本地连接:IP为127.0.0.1

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

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

2.使用远程桌面连接

3.连接成功

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

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

    1.结合现状 功能分析 该功能基于上个项目的改进,主要是通过对服务器端代码的修改,以及对客户端作少许修改,实现开启多客户端时,一个客户端发送消息,达到对所有客户端广播的效果.可参考网吧里的点歌系统,比 ...

  2. java实例练习——基于TCP/IP协议的多客户端通信

    先说一下大概的思路: 应用多线程来实现服务器与多客户端之间的通信 1.服务器端创建ServerSocket,循环调用accept()等待客户端连接: 2.客户端创建一个Socket并请求与服务器端连接 ...

  3. 写一个基于TCP协议套接字,服务端实现接收客户端的连接并发

    ''' 写一个基于TCP协议套接字,服务端实现接收客户端的连接并发 ''' client import socket import time client = socket.socket() clie ...

  4. 基于TCP/IP协议的C++网络编程(API函数版)

    源代码:http://download.csdn.net/detail/nuptboyzhb/4169959 基于TCP/IP协议的网络编程 定义变量——获得WINSOCK版本——加载WINSOCK库 ...

  5. 基于TCP的安卓服务器开发

    一.说明 前文介绍了基于安卓客户端的开发,在此基础上,进行少许改动即可开发出一款基于TCP的安卓服务器,理论知识请参见笔者上一篇博文,下面直接实践操作. 二.权限申明 <!--允许应用程序改变网 ...

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

    首先必须明确:TCP/IP模型中有四层结构:       应用层(Application Layer).传输层(Transport  Layer).网络层(Internet Layer  ).链路层( ...

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

    SignalR是一个.NET Core/.NET Framework的实时通讯的框架,一般应用在ASP.NET上,当然也可以应用在Winform上实现服务端和客户端的消息通讯,本篇随笔主要基于Sign ...

  8. mqtt 服务器与客户端通讯

    mqtt 服务器与客户端通讯. 服务器端 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ...

  9. 20181225 基于TCP/IP和基于UDP/IP的套接字编程

    一.TCP/IP的套接字编程 服务器端代码: import  socket​server = socket.socket() # 默认是基于TCP# 基于TCP的对象serve=socket.sock ...

随机推荐

  1. Codeforces 760B:Frodo and pillows(二分)

    http://codeforces.com/problemset/problem/760/B 题意:有n张床m个枕头,每张床可以有多个枕头,但是相邻的床的枕头数相差不能超过1,问第k张床最多能拥有的枕 ...

  2. K2工作流引擎Demo

    ---恢复内容开始--- 以前的工作都是电商网站形式的,从未接触过工作流相关工作,新公司是传统制造业行业,我进的这个组又是做工作流这块相关工作的,所以避免不了和工作流打交道. 这边工作流主要用K2来做 ...

  3. 02(c)多元无约束优化问题-牛顿法

    此部分内容接<02(a)多元无约束优化问题>! 第二类:牛顿法(Newton method) \[f({{\mathbf{x}}_{k}}+\mathbf{\delta })\text{ ...

  4. Spring Boot2(十三):整合定时任务发送邮件

    一.前言 主要玩一下SpringBoot的定时任务和发送邮件的功能.定时发送邮件,这在实际生成环境下主要用户系统性能监控时,当超过设定的阙值,就发送邮件通知预警功能.这里只通过简单的写个定时结合邮件通 ...

  5. SQLite的使用案例

    示例图 : activity_main.xml : <TextView android:id="@+id/t1" android:layout_width="wra ...

  6. 和朱晔一起复习Java并发(二):队列

    和朱晔一起复习Java并发(二):队列 老样子,我们还是从一些例子开始慢慢熟悉各种并发队列.以看小说看故事的心态来学习不会显得那么枯燥而且更容易记忆深刻. 阻塞队列的等待? 阻塞队列最适合做的事情就是 ...

  7. springcloud-注册中心快速构建

    1. 场景描述 springcloud提供了一整套可行的构建分布式系统的方案,使的企业/开发人员能够快速沟通分布式系统,今天快速构建下springcloud的注册中心Eureka. 2. 解决方案 2 ...

  8. numpy表示图片详解

    我自己的一个体会,在学习机器学习和深度学习的过程里,包括阅读模型源码的过程里,一个比较大的阻碍是对numpy掌握的不熟,有的时候对矩阵的维度,矩阵中每个元素值的含义晕乎乎的. 本文就以一个2 x 2 ...

  9. MFC在一个工程中启动其他工程的exe文件

    说明:有的时候把两个工程合并,但是偷懒不想在工程中添加代码,所以想到了这个办法,仅限偷懒哈哈哈哈 方法:新建一个主程序,在主程序的界面中添加按钮,在按钮的程序代码中添加以下语句: void CMain ...

  10. 个人永久性免费-Excel催化剂功能第90波-xml与json数据结构转换表格结构

    在网络时代,大量的数据交互以xml和json格式提供,特别是系统间的数据交互和网络WebAPI.WebService接口的数据提供,都是通过结构化的xml或json提供给其他应用调用返回数据.若能提供 ...