C#Socket网络Tcp通讯

Socket的通讯过程

  服务器端:

    01,申请一个socket

    02,绑定到一个IP地址和一个端口上

    03,开启侦听,等待接收连接

  客户端:

    01,申请一个socket

   02,连接服务器(指明IP地址和端口号)

   服务器端接收到连接请求后,产生一个新的socket(端口大于1024)与客户端建立连接并进行通信,原监听socket继续监听。

  注意:负责通信的Socket不能无限创建,创建的数量和操作系统有关。

 7.Socket的构造函数

    Public Socket(AddressFamily addressFamily,SocketType  socketType,ProtocolType  protocolTYpe)

    AddressFamily:指定Socket用来解析地址的寻址方案。例如:InterNetWork指示当Socket使用一个IP版本4地址连接

   SocketType:定义要打开的Socket的类型

   Socket类使用ProtocolType枚举向Windows  Sockets  API通知所请求的协议

注意:

   1,端口号必须在 1 和 65535之间,最好在1024以后。

   2,要连接的远程主机必须正在监听指定端口,也就是说你无法随意连接远程主机。

   3,如果只是在当前电脑上上运行需要使用127.0.0.1ip地址,192.x.x.x的需要使用网线连接其他主机。

如:

IPAddress addr = IPAddress.Parse("127.0.0.1");

IPEndPoint endp = new IPEndPoint(addr,,9000);

         服务端先绑定:serverWelcomeSocket.Bind(endp)

         客户端再连接:clientSocket.Connect(endp)

   3,一个Socket一次只能连接一台主机

   4,Socket关闭后无法再次使用

  5,每个Socket对象只能与一台远程主机连接。如果你想连接到多台远程主机,你必须创建多个Socket对象。

8.Socket常用类和方法

  相关类:

   IPAddress:包含了一个IP地址

   IPEndPoint:包含了一对IP地址和端口号

 方法:

   Socket():创建一个Socket

   Bind():绑定一个本地的IP和端口号(IPEndPoint)

   Listen():让Socket侦听传入的连接吃那个病,并指定侦听队列容量

   Connect():初始化与另一个Socket的连接

   Accept():接收连接并返回一个新的Socket

   Send():输出数据到Socket

   Receive():从Socket中读取数据

   Close():关闭Socket,销毁连接

  接下来,我们同一个简单的服务器和客户端通信的案例,来看下Sokcet的具体用法,效果图如下:

 

下面是实现的代码功能:

编写工具:VS2015


服务器代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SocketServer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //关闭跨线程访问
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
           
        }
        //获取通信用的Socekt
        Dictionary<string, Socket> dic = new Dictionary<string, Socket>();
        //消息显示
        void  showlog(string str)
        {
            TB_Info_receive.AppendText(str+"\r\n");
        }
        /// <summary>
        /// 创建实时等待客户端连接的套接字
        /// </summary>
        /// <param name="o"></将套接字传递到创建连接上面去>
        void AcceptInfo(object o)
        {
            Socket socket = o as Socket;
            while (true)
            {
                try
                {
                    Socket AcSocket=  socket.Accept();
                    //获取远程客户端的IP和端口号
                    string point = AcSocket.RemoteEndPoint.ToString();
                    showlog(point + "连接成功");
                    //往客户端列表里面追加客户端
                    ComB_Connet_ClientNum.Items.Add(point);
                    //往纪律通讯的键和值里面追加连接的客户端信息
                    dic.Add(point,AcSocket);
                    //接受消息
                    Thread AC = new Thread(receiver);
                    AC.IsBackground = true;
                    AC.Start(AcSocket);

                }
                catch (Exception ex)
                {
                   
                    showlog(ex.Message);
                    break;
                }
            }
        }
        /// <summary>
        /// 接受消息
        /// </summary>
        /// <param name="o"></将通讯的套接字传送到接受消息创建接受消息的套接字>
        private void receiver(Object o)
        {
            Socket client = o as Socket;
            while (true)
            {
                try
                {
                    //定义一个接收的BUffer存放客户端发送过来的数据
                    byte[] buffer = new byte[1024 * 1024];
                    //将接收过来的数据存放再buffer里面,并且返回接受的实际数据长度
                    int Num = client.Receive(buffer);
                    //将字节转换成字符串
                    string words = Encoding.UTF8.GetString(buffer, 0, Num);
                    showlog(client.RemoteEndPoint.ToString() + ":" + words);
                }
                catch (Exception ex)
                {

                    showlog(ex.Message);
                    break;
                }
            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                showlog(TB_Info_Send.Text);
                string ip = ComB_Connet_ClientNum.Text;
                byte[] buffer = Encoding.UTF8.GetBytes(TB_Info_Send.Text);
                dic[ip].Send(buffer);
            }
            catch (Exception ex)
            {

                showlog(ex.Message);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //获取窗口的IP和端口号
            IPAddress ip = IPAddress.Parse(TB_Server_ip.Text);
            IPEndPoint point = new IPEndPoint(ip, int.Parse(TB_point.Text));
            //创建套接字以及设置参数
            //创建监听用的Socket
            /* AddressFamily.InterNetWork:使用 IP4地址。
            SocketType.Stream:支持可靠、双向、基于连接的字节流,而不重复数据。此类型的 Socket 与单个对方主机进行通信,并且在通信开始之前需要远程主机连接。Stream 使用传输控制协议 (Tcp) ProtocolType 和 InterNetworkAddressFamily。
            ProtocolType.Tcp:使用传输控制协议。
            使用IPv4地址,流式socket方式,tcp协议传递数据
            创建好socket后,必须告诉socket绑定的IP地址和端口号。
             */
            //让socket监听point
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                //绑定端口号
                socket.Bind(point);
                //监听端口号以及 设置监听的最大个数
                socket.Listen(10);
                showlog("服务器开始监听");
                Thread thread = new Thread(AcceptInfo);
                thread.IsBackground = true;
                thread.Start(socket);
            }
            catch (Exception ex)
            {

                showlog(ex.Message);

            }
        }
    }
}
 


客户端实现代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ScoketClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }
        Socket Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private void BT_statrconnet_Click(object sender, EventArgs e)
        {
            IPAddress ip = IPAddress.Parse(TB_Server_ip.Text);
            IPEndPoint point = new IPEndPoint(ip, int.Parse(TB_point.Text));
          
            Client.Connect(point);
            showlog("连接成功");
            showlog("服务器" + Client.RemoteEndPoint.ToString());
            showlog("客户端" + Client.LocalEndPoint.ToString());
            Thread thread = new Thread(receiver);
            thread.IsBackground = true;
            thread.Start();
        }

        private void receiver()
        {
            while (true)
            {
                try
                {
                    byte[] buffer = new byte[1024 * 1024];
                    int Num = Client.Receive(buffer);
                    string s = Encoding.UTF8.GetString(buffer, 0, Num);
                    showlog(Client.RemoteEndPoint.ToString() + ":" + s);
                }
                catch (Exception ex)
                {

                    showlog(ex.Message);
                    break;

                }
            }
        }

        void showlog(string str)
        {
            TB_Info_receive.AppendText(str + "\r\n");
        }
        private void Form1_Load(object sender, EventArgs e)
        {

        }
        /// <summary>
        /// 发送消息给服务器
        /// </summary>
        /// <param name="sender"></种类>
        /// <param name="e"></种类的个数>
        private void BT_send_info_Click(object sender, EventArgs e)
        {
            if (Client!=null)
            {
                try
                {
                    showlog(TB_Info_Send.Text);
                    byte[] buffer = Encoding.UTF8.GetBytes(TB_Info_Send.Text);
                    Client.Send(buffer);                }
                catch (Exception ex)
                {

                    showlog(ex.Message);
                }
            }
        }
    }
}
 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值