首页 > 代码库 > Socket 网络编程

Socket 网络编程

<.>

客户端要连接服务器:首先要知道服务器的IP地址。而服务器里有很多的应用程序,每一个应用程序对应一个端口号
所以客户端想要与服务器中的某个应用程序进行通信就必须要知道那个应用程序的所在服务器的IP地址,及应用程序所对应的端口号

TCP协议:安全稳定,一般不会发生数据丢失,但是效率低。利用TCP发生数据一般经过3次握手(所有效率低,自己百度三次握手)
UDP协议:快速,效率高,但是不稳定,容易发生数据丢失(没有经过三次握手,不管服务器有空没空,信息全往服务器发,所有效率搞,但服务器忙的时候就没办法处理你的数据,容易造成数据丢失,不稳定)

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

namespace Socket通信
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            
            InitializeComponent();
            this.txtPort.Text = "5000";
            this.txtIp.Text = "192.168.137.1";
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            //当点击开始监听的时候,在服务器端创建一个负责监听IP地址跟端口号的Socket
            Socket socketWatch = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

            //Any:提供一个 IP 地址,指示服务器应侦听所有网络接口上的客户端活动。此字段为只读。
            IPAddress ip = IPAddress.Any;

            //创建端口号对象;将txtPort.Text控件的值设为服务端的端口号
            IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));

            //监听
            socketWatch.Bind(point);
            ShowMsg("监听成功");

            socketWatch.Listen(10);//连接队列的最大长度 ;即:一个时间点内最大能让几个客户端连接进来,超过长度就进行排队

            //等待客户端连接;Accept()这个方法能接收客户端的连接,并为新连接创建一个负责通信的Socket
            Thread th = new Thread(Listen); //被线程执行的方法如果有参数的话,参数必须是object类型

            Control.CheckForIllegalCrossThreadCalls = false; //因为.net不允许跨线程访问的,所以这里取消跨线程的检查。.net不检查是否有跨线程访问了,所有就不会报: “从不是创建控件“txtLog”的线程访问它” 这个错误了,从而实现了跨线程访问

            th.IsBackground = true; //将th这个线程设为后台线程。

            //Start(object parameter); parameter:一个对象,包含线程执行的方法要使用的数据,即线程执行Listen方法,Listen的参数
            th.Start(socketWatch);  //这个括号里的参数其实是Listen()方法的参数。因为Thread th = new Thread(Listen)这个括号里只能写方法名(函数名) 但是Listen()方法是有参数的,所有就要用Start()方法将它的参数添加进来
            
            
        }



        /// <summary>
        /// 等待客户端连接,如果监控到有客户端连接进来就创建一个与之通信的Socket
        /// </summary>
        /// <param name="o"></param>
        void Listen(object o) //这里为什么不直接传递Socket类型的参数呢? 原因是:被线程执行的方法如果有参数的话,参数必须是object类型
        {
            Socket socketWatch = o as Socket;
            

            while (true) //为什么这里要有个while循环?因为当一个人连接进来的时候创建了与之通信的Socket后就程序就会往下执行了,就不会再回来为第二个人的连接创建负责通信的Socket了。(应该是每个人(每个客户端)创建一个与之通信的Socket)所以要写在循环里。
            {
                //等待客户端连接;Accept()这个方法能接收客户端的连接,并为新连接创建一个负责通信的Socket
                Socket socketSend = socketWatch.Accept();

                dic.Add(socketSend.RemoteEndPoint.ToString(), socketSend); //(根据客户端的IP地址和端口号找负责通信的Socket,每个客户端对应一个负责通信的Socket),ip地址及端口号作为键,将负责通信的Socket作为值填充到dic键值对中。

                //我们通过负责通信的这个socketSend对象的一个RemoteEndPoint属性,能够拿到远程连过来的客户端的Ip地址跟端口号
                ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + "连接成功");//效果:192.168.1.32:连接成功

                comboBox1.Items.Add(socketSend.RemoteEndPoint.ToString()); //将连接过来的每个客户端都添加到combBox控件中。


                //客户端连接成功后,服务器应该接收客户端发来的消息。 
                Thread getdata = http://www.mamicode.com/new Thread(GetData);>


开打开始命令  cmd   telnet 10.18.16.46 5000    即telnet 服务器ip地址  绑定的端口号




Socket 网络编程