学习地址 http://www.sikiedu.com/course/63/task/1478/show
IP和端口号
ip 找到电脑地址
同一个路由器,分配过去电脑的ip就是局域网ip,dos系统输入ipconfig能搜索自己电脑的局域网ip,在百度搜索ip会弹出本机的外网ip
端口号 使用设定的软件访问电脑,所以每个软件的端口号也是唯一的
一般知名的端口号在0-1023,而我们经常使用的自定义/动态分配的端口号则一般在49152-65535之间
不要申请公认的端口,例如80
为了不跟别的软件产生端口冲突,我们可以查看电脑各个软件使用的端口:https://jingyan.baidu.com/article/fec7a1e5f944211190b4e719.html
TCP的三次握手,四次挥手
建立连接的时候需要经过三次握手进行连接,然后断开连接的时候需要经过四次挥手进行断开连接
创建服务器端
1使用ip4地址,2使用数据流,使用tcp协议
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets; //必须引入的命名空间
using System.Net;
namespace TCP服务器端
{
class Program
{
static void Main(string[] args)
{
//ip地址 //使用数据流 //指定使用的协议
Socket serverSokect = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//本机10.66.20.118 本机ip 万能本地ip 127.0.0.1,,当你客户端进行连接的时候就要连接服务的ip
//IPAdress 就是ip地址,,ipEndPoint 就是代表 “ip:端口号”
IPAddress ipAdress = IPAddress.Parse("10.66.20.118"); //创建一个ip地址
IPEndPoint ipEndPoint = new IPEndPoint(ipAdress, 88); //申请一个端口号
serverSokect.Bind(ipEndPoint); //申请完了端口号和ip地址,绑定到服务端
serverSokect.Listen(0); //一次性允许处理的监听,如果设置10个,就是我的队列里面一次性只对10个客户端进行数据监听
//0个的话就是不限制,这个数据不是代表允许连接的数量,是代表处理连接的队列
Socket clientSocket=serverSokect.Accept(); //接受一个客户端的连接,程序在这个时候会暂停,直到有一个客户端进行了连接
string msg = "hello client! 你好";
byte[] data=System.Text.Encoding.UTF8.GetBytes(msg); //在进行网络传输的时候,只能传输字节,就是0和1这些数据,所以我们
//要把字符串转成byte数组传输出去
clientSocket.Send(data); //这样我就向客户端发送一条消息
//接收到客户端发来的消息
byte[] dataBuffer = new byte[1024]; //创建一个缓冲区,1024是确保一般大小的数据长度满足
int count= clientSocket.Receive(dataBuffer); //获取接收到数据的长度
string msgReceive = System.Text.Encoding.UTF8.GetString(dataBuffer,0,count); //这样就把传进来的数据转化为string
//从第几个dataBuffer的第几个数据进行截取,这个参数必须指定的
Console.WriteLine("客户端的消息:"+msg);
clientSocket.Close(); //这个只是关闭跟客户端的连接
serverSokect.Close(); //这个是关闭服务器自身的连接
}
}
}
创建一个客户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace TCP客户端
{
class Program
{
static void Main(string[] args)
{
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
///这个是创建一个客户端,这个跟服务器的创建是一样的
clientSocket.Connect(new IPEndPoint(IPAddress.Parse("10.66.20.118"), 88));//这样就跟服务器端进行了指定的ip和端口号进行了连接
///这样我们首先接收一下服务器端的消息
byte[] dataBuffer = new byte[1024];
int count = clientSocket.Receive(dataBuffer);
string msgReceive = System.Text.Encoding.UTF8.GetString(dataBuffer, 0, count);
Console.WriteLine(msgReceive);
//向客户端发送一条消息
string s = Console.ReadLine(); //等待输入
clientSocket.Send(Encoding.UTF8.GetBytes(s)); //转成数据0,1进行发送
clientSocket.Close(); //关闭客户端
}
}
}
实行服务器异步接收消息
服务器端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets; //必须引入的命名空间
using System.Net;
namespace TCP服务器端
{
class Program
{
static void Main(string[] args)
{
startServerAsync();
Console.ReadKey();
}
/// <summary>
/// 异步接收数据
/// </summary>
static void startServerAsync()
{
//ip地址 //使用数据流 //指定使用的协议
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//本机10.66.20.118 本机ip 万能本地ip 127.0.0.1,,当你客户端进行连接的时候就要连接服务的ip
//IPAdress 就是ip地址,,ipEndPoint 就是代表 “ip:端口号”
IPAddress ipAdress = IPAddress.Parse("10.66.20.118"); //创建一个ip地址
IPEndPoint ipEndPoint = new IPEndPoint(ipAdress, 88); //申请一个端口号
serverSocket.Bind(ipEndPoint); //申请完了端口号和ip地址,绑定到服务端
serverSocket.Listen(0); //一次性允许处理的监听,如果设置10个,就是我的队列里面一次性只对10个客户端进行数据监听
//0个的话就是不限制,这个数据不是代表允许连接的数量,是代表处理连接的队列
//Socket clientSocket = serverSokect.Accept(); //接受一个客户端的连接,程序在这个时候会暂停,直到有一个客户端进行了连接
//表示开始监听数据的接收
serverSocket.BeginAccept(AcceptCallBack, serverSocket);
}
static byte[] dataBuffer = new byte[1024];
/// <summary>
/// 当我们接收到一条消息的时候我们会用这个方法去处理
/// </summary>
/// <param name="ar"></param>
static void ReceiveCallBack(IAsyncResult ar)
{
Socket clientSocket=null;
try //创建异常捕捉
{
clientSocket = ar.AsyncState as Socket;
int count = clientSocket.EndReceive(ar); //可以知道接收的消息有多长
if (count == 0) {
clientSocket.Close();
return;
}
string msg = Encoding.UTF8.GetString(dataBuffer, 0, count); //这个完成接收
Console.WriteLine("从客户端接收到的消息:" + msg);
clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket); //函数递归回调
}
catch (Exception e)
{
Console.WriteLine(e);
if (clientSocket != null)
{
clientSocket.Close();
}
}
}
static void AcceptCallBack(IAsyncResult ar) {
Socket serverSocket = ar.AsyncState as Socket;
Socket clientSocket=serverSocket.EndAccept(ar);
string msg = "hello client! 你好";
byte[] data = System.Text.Encoding.UTF8.GetBytes(msg);
clientSocket.Send(data);
clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
serverSocket.BeginAccept(AcceptCallBack, serverSocket);
}
/// <summary>
/// 这是一个同步消息的服务端发送
/// </summary>
void startServerSync()
{
//ip地址 //使用数据流 //指定使用的协议
Socket serverSokect = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//本机10.66.20.118 本机ip 万能本地ip 127.0.0.1,,当你客户端进行连接的时候就要连接服务的ip
//IPAdress 就是ip地址,,ipEndPoint 就是代表 “ip:端口号”
IPAddress ipAdress = IPAddress.Parse("10.66.20.118"); //创建一个ip地址
IPEndPoint ipEndPoint = new IPEndPoint(ipAdress, 88); //申请一个端口号
serverSokect.Bind(ipEndPoint); //申请完了端口号和ip地址,绑定到服务端
serverSokect.Listen(0); //一次性允许处理的监听,如果设置10个,就是我的队列里面一次性只对10个客户端进行数据监听
//0个的话就是不限制,这个数据不是代表允许连接的数量,是代表处理连接的队列
Socket clientSocket = serverSokect.Accept(); //接受一个客户端的连接,程序在这个时候会暂停,直到有一个客户端进行了连接
string msg = "hello client! 你好";
byte[] data = System.Text.Encoding.UTF8.GetBytes(msg); //在进行网络传输的时候,只能传输字节,就是0和1这些数据,所以我们
//要把字符串转成byte数组传输出去
clientSocket.Send(data); //这样我就向客户端发送一条消息
//接收到客户端发来的消息
byte[] dataBuffer = new byte[1024]; //创建一个缓冲区,1024是确保一般大小的数据长度满足
int count = clientSocket.Receive(dataBuffer); //获取接收到数据的长度
string msgReceive = System.Text.Encoding.UTF8.GetString(dataBuffer, 0, count); //这样就把传进来的数据转化为string
//从第几个dataBuffer的第几个数据进行截取,这个参数必须指定的
Console.WriteLine("客户端的消息:" + msgReceive);
Console.ReadKey();
clientSocket.Close(); //这个只是关闭跟客户端的连接
serverSokect.Close(); //这个是关闭服务器自身的连接
}
}
}
客户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace TCP客户端
{
class Program
{
static void Main(string[] args)
{
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
///这个是创建一个客户端,这个跟服务器的创建是一样的
clientSocket.Connect(new IPEndPoint(IPAddress.Parse("10.66.20.118"), 88));//这样就跟服务器端进行了指定的ip和端口号进行了连接
///这样我们首先接收一下服务器端的消息
byte[] dataBuffer = new byte[1024];
int count = clientSocket.Receive(dataBuffer);
string msgReceive = System.Text.Encoding.UTF8.GetString(dataBuffer, 0, count);
Console.WriteLine(msgReceive);
while (true) {
string s = Console.ReadLine(); //等待输入
if (s == "c") {
clientSocket.Close(); return;
}
clientSocket.Send(Encoding.UTF8.GetBytes(s)); //转成数据0,1进行发送
}
//向客户端发送一条消息
Console.ReadKey();
clientSocket.Close(); //关闭客户端
}
}
}