基于C#的socket编程的TCP同步实现
该博客源著地址https://www.cnblogs.com/sunev/archive/2012/08/05/2604189.html
一、摘要
总结一下基于C#的TCP传输协议的涉及到的常用方法及同步实现。
二、实验平台
Visual Studio 2010
三、socket编程的一些常用方法(同步实现)
3.1 命名空间
需要添加的命名空间
using System.Net;
using System.Net.Socket;
3.2 构造新的socket对象
socket原型:
public socket (AddressFamily addressFamily,SocketType sockettype,ProtocolType protocolType)
(1) AddressFamily 用来指定socket解析地址的寻址方案,Inte.Network标示需要ip版本4的地址,Inte.NetworkV6需要ip版本6的地址;
(2) SocketType 参数指定socket类型,Raw支持基础传输协议访问,Stream支持可靠,双向,基于连接的数据流;
(3) ProtocolType 表示socket支持的网络协议,如常用的TCP和UDP协议。
3.3 定义主机对象
(1) IPEndPoint类
原型:
a)
public IPEndPoint(IPAddress address,int port)
参数address可以直接填写主机的IP,如"192.168.2.1";
b)
public IPEndPoint(long address,int port)
参数address整型int64如123456,参数port端口int32,如6655。
(2) 利用DNS服务器解析主机,使用Dns.Resolve方法
原型:
public static IPHostEntry Resolve(string hostname)
参数:待解析的主机名称,返回IPHostEntry类值,IPHostEntry为Inte.Net主机地址信息提供容器,该容器提供存有IP地址列表,主机名称等。
(3) Dns.GetHostByName获取本地主机名称
原型:
public static IPHostEntry GetHostByName(string hostname)
(4) GetHostByAddress
原型:
a)
public static IPHostEntry GetHostByAddress(IPAddress address)
参数:IP地址。
b)
public static IPHostEntry GetHostByAddress(string address)
参数:IP地址格式化字符串。
3.4 端口绑定和监听
同步套接字服务器主机的绑定和端口监听,Socket类的Bind(绑定主机),Listen(监听端口),Accept(接收客户端的连接请求)。
(1) Bind
原型:
public void Bind(EndPoint LocalEP)
参数为主机对象 IPEndPoint
(2) Listen
原型:
public void Listen(int backlog)
参数整型数值,挂起队列最大值
(3) accept
原型:
public socket accept()
返回为套接字对象
3.5 socket的发送和接收方法
(1) 发送数据
a)socket类的send方法
原型一:
public int Send(byte[] buffer)
参数:待发送的字节数组;
原型二:
public int Send(byte[],SocketFlags)
SocketFlags成员列表:
DontRoute不使用路由表发送,
MaxIOVectorLength为发送和接收数据的wsabuf结构数量提供标准值,
None 不对次调用使用标志,
OutOfBand消息的部分发送或接收,
Partial消息的部分发送或接收,
Peek查看传入的消息。
原型三:
public int Send(byte[],int,SocketFlags)
参数二要发送的字节数
原型四:
public int Send(byte[],int,int,SocketFlags)
参数二为Byte[]中开始发送的位置
b) NetWordStream类的Write方法
原型:
public override void write(byte[] buffer,int offset,int size)
参数分别为:字节数组,开始字节位置,总字节数。
(2) 接收数据
a) Socket类Receive方法
原型一:
public int Receive(byte[] buffer)
原型二:
public int Receive(byte[],SocketFlags)
原型三:
public int Receive(byte[],int,SocketFlags)
原型四:
public int Receive(byte[],int,int,SocketFlags)
Socket类Receive方法的相关参数可参看Socket类Send方法中的参数。
b) NetworkStream类的Read方法
public override int Read(int byte[] buffer,int offset,int size)
参数可参看NetworkStream类的Write方法。
四、TCP传输协议的同步实现
4.1 服务器端编程的步骤:
(1) 创建套接字;
(2) 绑定套接字到一个IP地址和一个端口上(bind());
(3)将套接字设置为监听模式等待连接请求(listen());
(4)请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());
(5)用返回的套接字和客户端进行通信(send()/recv());
(6)返回,等待另一连接请求;
(7)关闭套接字。
服务器端代码:

using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Text; namespace net
{
class Program
{
static void Main(string[] args)
{
//定义接收数据长度变量
int recv;
//定义接收数据的缓存
byte[] data = new byte[1024];
//定义侦听端口
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 5566);
//定义套接字类型
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//连接
socket.Bind(ipEnd);
//开始侦听
socket.Listen(10);
//控制台输出侦听状态
Console.Write("Waiting for a client");
//一旦接受连接,创建一个客户端
Socket client = socket.Accept();
//获取客户端的IP和端口
IPEndPoint ipEndClient = (IPEndPoint)client.RemoteEndPoint;
//输出客户端的IP和端口
Console.Write("Connect with {0} at port {1}", ipEndClient.Address, ipEndClient.Port);
//定义待发送字符
string welcome = "Welcome to my server";
//数据类型转换
data = Encoding.ASCII.GetBytes(welcome);
//发送
client.Send(data, data.Length, SocketFlags.None);
while (true)
{
//对data清零
data = new byte[1024];
//获取收到的数据的长度
recv = client.Receive(data);
//如果收到的数据长度为0,则退出
if (recv == 0)
break;
//输出接收到的数据
Console.Write(Encoding.ASCII.GetString(data, 0, recv));
//将接收到的数据再发送出去
client.Send(data, recv, SocketFlags.None);
}
Console.Write("Disconnect form{0}", ipEndClient.Address);
client.Close();
socket.Close();
}
}
}

4.2 客户端编程的步骤:
(1) 创建套接字;
(2) 向服务器发出连接请求(connect());
(3) 和服务器端进行通信(send()/recv());
(4) 关闭套接字。
客户端代码:

using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Text; namespace client
{
class Program
{
static void Main(string[] args)
{
//定义发送数据缓存
byte[] data = new byte[1024];
//定义字符串,用于控制台输出或输入
string input, stringData;
//定义主机的IP及端口
IPAddress ip = IPAddress.Parse("127.0.0.1");
IPEndPoint ipEnd = new IPEndPoint(ip, 5566);
//定义套接字类型
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//尝试连接
try
{
socket.Connect(ipEnd);
}
//异常处理
catch (SocketException e)
{
Console.Write("Fail to connect server");
Console.Write(e.ToString());
return;
}
//定义接收数据的长度
int recv = socket.Receive(data);
//将接收的数据转换成字符串
stringData = Encoding.ASCII.GetString(data, 0, recv);
//控制台输出接收到的数据
Console.Write(stringData); //定义从键盘接收到的字符串
input = Console.ReadLine(); //将从键盘获取的字符串转换成整型数据并存储在数组中
data = Encoding.ASCII.GetBytes(input);
//发送该数组
socket.Send(data, data.Length, SocketFlags.None); while (true)
{
// //如果字符串是"exit",退出while循环
if (input == "exit")
{
break;
}
//对data清零
data = new byte[1024];
//定义接收到的数据的长度
recv = socket.Receive(data);
//将接收到的数据转换为字符串
stringData = Encoding.ASCII.GetString(data, 0, recv);
//控制台输出字符串
Console.Write(stringData);
//发送收到的数据
socket.Send(data, recv, 0); }
Console.Write("disconnect from server");
socket.Shutdown(SocketShutdown.Both);
socket.Close();
} }
}

上述代码实现了,当连接建立之后,客户端向服务器端发送键盘输入的字符,服务器端收到字符后,显示在控制台并发送给客户端,客户端收到字符后,显示在控制台并再次发送给服务器端,如此循环。
五、实验结果
先后运行服务器端程序和客户端程序,控制台界面如下:
图1 服务器端控制台
当连接建立后,服务器端控制台显示等待客户端的状态"Waiting for a client",并打印出连接信息。
图2 客户端控制台
当连接建立后,客户端收到来自服务器端发送的字符串"Welcome to my server"。
之后,客户端通过键盘发送数据,二者循环接收并发送,控制台分别如下:
图3 服务器控制台
图4 客户端控制台
六、几点说明
6.1 传输速度
(1) 增大发送和接收的数组可提升传输速度,即增加一次实际发送数据的数量可以提高传输速度,但数组中数据的个数也不能一味的增大。需要说明的,由于地层MIT的限制,底层具体实现的时候每次发送的数据仍是不超过1510个的。
(2) 将控制台界面最小化后,速度也会有翻倍的提升。
6.2 MFC的转换
为了使传输协议更有可观性和使用性,通常做成MFC的样式,具体的使用已在"基于TCP协议的网络摄像头的设计与实现"应用。
基于C#的socket编程的TCP同步实现的更多相关文章
- 基于C#的socket编程的TCP异步实现
一.摘要 本篇博文阐述基于TCP通信协议的异步实现. 二.实验平台 Visual Studio 2010 三.异步通信实现原理及常用方法 3.1 建立连接 在同步模式中,在服务器上使用Accept方法 ...
- (转)基于C#的socket编程的TCP异步实现
一.摘要 本篇博文阐述基于TCP通信协议的异步实现. 二.实验平台 Visual Studio 2010 三.异步通信实现原理及常用方法 3.1 建立连接 在同步模式中,在服务器上使用Accept方法 ...
- 计算机网络(十三),Socket编程实现TCP和UDP
十三.Socket编程实现TCP和UDP 1.TCP (1)TCPServer.java类 package com.interview.javabasic.socket; import com.int ...
- 基于MFC的socket编程(异步非阻塞通信)
对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手.许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等,初学者往往迷惑不清, ...
- 基于win32的socket编程及程序实现
初步研究了win32平台的Windows Sockets,它是Microsoft Windows的网络程序设计接口,它是从Berkeley Sockets扩展而来的,以动态链接库的形式提供给我们使用. ...
- socket编程实现tcp服务器_C/C++
1. 需求分析 实现一个回声服务器的C/S(客户端client/服务器server)程序,功能为客户端连接到服务器后,发送一串字符串,服务器接受信息后,返回对应字符串的大写形式给客户端显示. 例如: ...
- day8---多线程socket 编程,tcp粘包处理
复习下socket 编程的步骤: 服务端: 1 声明socket 实例 server = socket.socket() #括号里不写 默认地址簇使用AF_INET 即 IPv4 ...
- 基于java的socket编程
#开头的废话#学习java已经半个月了,原本在抠教材里面的字眼时,觉得教材好厚,要看完不知道要到猴年马月去了.突然在网上看到一个教程,里面老师说学编程语言书不用太细看,看个大概,知道里面讲些什么就好, ...
- 基于MFC的socket编程
网络编程 1.windows 套接字编程(开放的网络编程接口)添加头文件#include<windows.h> 2.套接字及其分类 socket分为两种:(1)数据报socket:无连接套 ...
随机推荐
- JavaScript中的运算符和语句
一.JavaScript的运算符 a.基本的算术运算符(+.-.*./.%) -.*./.%运算符会在必要的时候将操作数转换为数字,无法转换成数字的操作数将会转换成NaN,相应的运算结果也是NaN. ...
- Fio 输出内容的解释
Fio 输出内容的解释 feilianbb 2016-01-11 16:18:54 27828 收藏 19 文章标签: Linux 存储 Fio SSD 性能 翻译原文来源 https://t ...
- http://www.loongnix.org/index.php/Lbrowser
http://www.loongnix.org/index.php/Lbrowser 浏览器是桌面应用的核心API软件,龙芯中科早在2011年就开始组建浏览器研发团队开展基于gecko.blink等内 ...
- 华为eNSP模拟器— telnet实验
华为eNSP模拟器-telnet实验 一.实验一 路由交换之间实现telnet登陆 实验拓扑 实验目的: 路由器作为 telnet 服务器 交换机作为客户端去连接路由器 实验步骤: 路由器配置 < ...
- ltp循环跑
e]# cat r3.sh#!/bin/bashi=1for ((; i<=1000; i++))do/opt/ltp/runltp -s fmtmsg01 -p -l -t -l /home/ ...
- ARP欺骗-断网小技巧
警告:请勿用于非法用途,后果自负! 环境: 攻击方: Kali Linux 被攻击方: Windows XP 二者在同一局域网下 步骤 1.查看Windows的IP,联网状态 在Windows的cmd ...
- Linux中级之ansible配置(playbook)
一.playbooks 如果用模块形式一般有幂等性,如果用shell或者command没有幂等性 playbooks相当于是shell脚本,可以把要执行的任务写到文件当中,一次执行,方便调用 task ...
- 11.10 chkconfig:管理开机服务
chkconfig 命令是Redhat系列的Linux系统中的系统服务管理工具,它可以用于查询和更新不同的运行等级下系统服务的启动状态. chkconfig命令的参数选项及说明 --list 显 ...
- MyBatis 环境搭建(四)
MyBatis 引言 在回顾JDBC时,我们已经创建有 Java 工程,而且也已经导入 mysql 依赖包,这里就直接在原有工程上搭建MyBatis环境,以及使用MyBatis来实现之前用 JDBC ...
- C# Asp.Net 实现PPT/PDF转成图片(不依赖office)
最近公司有个需求,将PPT课件转成图片列表,然后在前端展示成轮播图,于是一开始通过Microsoft.Office.Interop.PowerPoint包实现了这个需求具体代码如下: /// < ...