如果想开发一个基于TCP/IP协议的网络程序,应用程序之间则主要通过Socket交换数据

.NET Socket支持四种编程模式

1.居于阻塞模式的Socket编程

2.”非阻塞“模式的Socket编程

3.使用IAsyncResult的异步编程模式

4.使用EAP的异步编程模式

为什么要学Socket

开始写代码 :

Socket从信息的”发送“与”接收“角度,Socket分为两类:

Server端Socket:它在指定的端口上监听,等待客户端的连接请求,并且向客户端发送接收数据

Client端Socket:它尝试连接Server端的Socket,在连接成功之后,与Server端应用程序相互收发数据

首先开发服务端的程序:

准备:用于绑定的终结点IpEndPoint

//准备:用于绑定的终结点
IPAddress ipAddress = AddressHelper.GetLocalhostIPv4Address().First();
int LocalPort = AddressHelper.GetOneAvaiablePortInLocalhost();
IPEndPoint ipEnd = new IPEndPoint(ipAddress, LocalPort);

1.创建Socket对象

//1.创建Socket
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

2.绑定终结点

//2. Socket绑定终结点
server.Bind(ipEnd);

3.监听

//3.监听
server.Listen();
Console.WriteLine("主机 {0} 正在监听端口 {1} ,等待客户端连接……", ipAddress, ipEnd.Port);

4.响应连接请求:

//4. 如果有连接 响应连接请求
Socket client = server.Accept(); IPEndPoint clientIpEnd = client.RemoteEndPoint as IPEndPoint;
Console.WriteLine("已接收客户端请求 客户端ip地址{0},端口号{1}", clientIpEnd.Address, clientIpEnd.Port);
string welcome = "欢迎使用本网络服务,请输入字符串 输入exit退出";
//将欢迎信息发送给客户端
data = Encoding.UTF8.GetBytes(welcome);
client.Send(data, data.Length, SocketFlags.None);

5.服务端Socket接收数据,处理数据,在客户端要求断开连接的时候,关闭socket

 while (true)
{
//TODO 实现可以同时连接多个客户端的程序 实现两个客户端互相通信
//5.服务端Scoket开始接收客户端的数据,并将响应信息传回客户端
int recv = client.Receive(data);
string message = Encoding.UTF8.GetString(data, , recv);
if (message.Equals("exit"))
{
//关闭Socket
Console.WriteLine("客户端{0}已断开连接",clientIpEnd.Address);
client.Close();
break;
}
else
{
//将响应信息传给客户端
Console.WriteLine("客户端发来消息:{0}", message);
string sendMsg = string.Format("服务器已经收到您的消息:{0}", message);
client.Send(Encoding.UTF8.GetBytes(sendMsg));
} }
}

2-5过程为了简化socket的操作,我用using(server){2-5的过程} 把2-5的代码给包起来了

using (server)
{ //2. Socket绑定终结点
//3.监听
//4. 如果有连接 响应连接请求
//5.服务端Scoket开始接收客户端的数据,并将响应信息传回客户端
}

服务端就是这样子了

下面是客户端Client

1.创建Socket对象

2.调用socket对象的Connect的方法创建连接

3.发送数据

整体代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using MyNetworkLibrary; namespace MyClientApp
{
class Program
{
private const int BufferSize = ;
static void Main(string[] args)
{
byte[] data = new byte[BufferSize];
IPEndPoint ipEnd = AddressHelper.GetRemoteMachineIPEndPoint();
//1.创建Socket对象
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//2.调用Connect创建连接
try
{
client.Connect(ipEnd.Address, ipEnd.Port);
Console.WriteLine("服务器端已连接");
}
catch (SocketException e)
{ Console.WriteLine("无法连接远程主机{0},原因{1},NativeErrorCode{2},SocketErrorCode{3}", ipEnd.Address, e.Message, e.NativeErrorCode, e.SocketErrorCode);
Console.WriteLine("敲任意键退出");
Console.ReadKey();
return;
}
string recvData = "";
int recv = client.Receive(data);
recvData = Encoding.UTF8.GetString(data, , recv);
Console.WriteLine(recvData); //发送数据
string UserInput = "";
while (true)
{
UserInput = Console.ReadLine();
if (string.IsNullOrEmpty(UserInput))
continue;
byte[] SendBytes = Encoding.UTF8.GetBytes(UserInput);
client.Send(SendBytes);
if (UserInput == "exit")
{
client.Shutdown(SocketShutdown.Both);
client.Close();
Console.WriteLine("您选择断开与服务器的连接");
break;
}
recv = client.Receive(data);
recvData = Encoding.UTF8.GetString(data, , recv);
Console.WriteLine(recvData);
}
Console.WriteLine("敲任意键退出...");
Console.ReadKey();
}
}
}

这里,我将服务端和客户端需要的一些数据封装到一MyNetworkLibrary类库中去,方便调用,和以后的扩展

代码贴一下

 using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading; namespace MyNetworkLibrary
{
public static class AddressHelper
{
/// <summary>
/// 获取本地IPv4地址的集合
/// </summary>
/// <returns></returns>
public static IPAddress[] GetLocalhostIPv4Address()
{
string LocalhostName = Dns.GetHostName();
IPHostEntry host = Dns.GetHostEntry(LocalhostName);
List<IPAddress> addresses = new List<IPAddress>();
foreach (IPAddress ipAddress in host.AddressList)
{
if(ipAddress.AddressFamily == AddressFamily.InterNetwork)
addresses.Add(ipAddress);
}
return addresses.ToArray();
}
/// <summary>
/// 以交互的方式生成有效的远程主机访问终结点,适用于控制台
/// </summary>
/// <returns></returns>
public static IPEndPoint GetRemoteMachineIPEndPoint()
{
IPEndPoint ipEnd = null;
try
{
Console.Write("请输入远程主机的ip地址:");
IPAddress ipAddress = IPAddress.Parse(Console.ReadLine());
Console.Write("请输入远程主机的端口号:");
int port = Convert.ToInt32(Console.ReadLine());
if (port > || port < )
{
throw new Exception("端口号为[1024,65535]之间整数");
}
ipEnd = new IPEndPoint(ipAddress,port); }
catch (ArgumentNullException)
{
Console.WriteLine("输入的数据有误!"); }
catch (FormatException)
{
Console.WriteLine("输入的数据有误!");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return ipEnd;
}
/// <summary>
/// 获取本机当前可用的端口号,此方法是线程安全的
/// </summary>
/// <returns></returns>
public static int GetOneAvaiablePortInLocalhost()
{
Mutex mtx = new Mutex(false, "MyNetworkLibrary.AddressHelper.GetOneAvailablePort");
try
{
mtx.WaitOne();
IPEndPoint ep = new IPEndPoint(IPAddress.Any,);
using (Socket tempSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp))
{
tempSocket.Bind(ep);
IPEndPoint ipEnd = tempSocket.LocalEndPoint as IPEndPoint;
return ipEnd.Port;
} }
finally
{
mtx.ReleaseMutex();
}
}
}
}

好啦 这样就写完一个简单的一对一的Socket网络程序了

看一下效果

Socket网络编程--初级的更多相关文章

  1. Linux Socket 网络编程

    Linux下的网络编程指的是socket套接字编程,入门比较简单.在学校里学过一些皮毛,平时就是自学玩,没有见识过真正的socket编程大程序,比较遗憾.总感觉每次看的时候都有收获,但是每次看完了之后 ...

  2. Python Socket 网络编程

    Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的,例如我们每天浏览网页.QQ ...

  3. Python全栈【Socket网络编程】

    Python全栈[socket网络编程] 本章内容: Socket 基于TCP的套接字 基于UDP的套接字 TCP粘包 SocketServer 模块(ThreadingTCPServer源码剖析) ...

  4. python之Socket网络编程

    什么是网络? 网络是由节点和连线构成,表示诸多对象及其相互联系.在数学上,网络是一种图,一般认为专指加权图.网络除了数学定义外,还有具体的物理含义,即网络是从某种相同类型的实际问题中抽象出来的模型.在 ...

  5. Python之路【第七篇】python基础 之socket网络编程

    本篇文章大部分借鉴 http://www.cnblogs.com/nulige/p/6235531.html python socket  网络编程 一.服务端和客户端 BS架构 (腾讯通软件:ser ...

  6. Socket网络编程-基础篇

    Socket网络编程 网络通讯三要素: IP地址[主机名] 网络中设备的标识 本地回环地址:127.0.0.1 主机名:localhost 端口号 用于标识进程的逻辑地址 有效端口:0~65535 其 ...

  7. Socket网络编程--FTP客户端

    Socket网络编程--FTP客户端(1)(Windows) 已经好久没有写过博客进行分享了.具体原因,在以后说. 这几天在了解FTP协议,准备任务是写一个FTP客户端程序.直接上干货了. 0.了解F ...

  8. windows下的socket网络编程

    windows下的socket网络编程 windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了, ...

  9. windows下的socket网络编程(入门级)

    windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了,这次因为需要做一个跨平台的网络程序,就先 ...

随机推荐

  1. send, sendto, sendmsg - 从套接字发送消息

    概述 #include <sys/types.h> #include <sys/socket.h> int send(int s, const void *msg, size_ ...

  2. dotNET面试(一)

    1.列举ASP.NET 页面之间传递值的几种方式. 1).使用QueryString, 如....?id=1; response. Redirect().... 2).使用Session变量 3).使 ...

  3. sublime text的快捷键

    Ctrl + Shift + P:调出命令板(Command Palette)Ctrl + `:调出控制台Ctrl + Enter:在当前行下面新增一行然后跳至该行Ctrl + Shift + Ent ...

  4. Codeforces 961E - Tufurama 树状数组

    转自:https://blog.csdn.net/my_sunshine26/article/details/79831362 题目大意: i从1开始 基本思路: 完全没思路,所以上来就二分,果不其然 ...

  5. 10.ThreadLocal

    /** * - void set(Object value)设置当前线程的线程局部变量的值. * - public Object get()该方法返回当前线程所对应的线程局部变量. * - publi ...

  6. nmap使用笔记

    扫描全端口判断服务 nmap ip -T4 -Pn -sV -p 1-65535 扫描端口并且标记可以爆破的服务 nmap ip --script=ftp-brute,imap-brute,smtp- ...

  7. 每天一个linux命令:mv(7)

    mv mv命令可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 在跨文件系统移动文件时,mv先拷贝,再将原有文件删除, ...

  8. 洛谷P2015 二叉苹果树(树状dp)

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...

  9. BZOJ 1005: [HNOI2008]明明的烦恼(高精度+prufer序)

    传送门 解题思路 看到度数和生成树个树,可以想到\(prufer\)序,而一张规定度数的图的生成树个数为\(\frac{(n-2)!}{\prod\limits_{i=1}^n(d(i)-1)!}\) ...

  10. 整合SSH

    Hibernate知识: 1.核心配置文件: 连接数据库信息.连接池配置 映射配置 Struts2: 1.相关操作: 创建方式: 写一个类,写上public String execute():方法 实 ...