您的位置:首页 > 其它

socket通信问题

2015-12-11 14:55 218 查看
TCP:面向连接的,所以在服务端绑定端口后,需要监听Listen()是否有客户端发送请求,有的话,Accept()建立一个新的socket对象,用于发送和接收信息,

就想先建造了一条高速路,再建造一辆货车拉货。

UDP:无连接的,所以在服务端绑定端口后,不需要监听Listen(),也不用建立一个新的socket对象用于接收发送信息,但是在发送和接收时,要讲本身的端口

做参数发送给对方,这样在交流时,对方才能确定自己。

UDP协议:

Client端:

static void Main(string[] args)
        {
            int port = 2001;
            string strHost = GetAddressIP();// "127.0.0.1";
            //  建立IP对象
            IPAddress ip = IPAddress.Parse(strHost);
            //  建立端口对象
            IPEndPoint ipe = new IPEndPoint(ip, port);

            //  创建socket对象
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            Console.WriteLine("连接中。。。");

            //  向服务器发送消息
            string strMsgToServe = "嗨,来自客户端的问候。。。";
            //  转成二进制发送到服务端
            byte[] bytMsgToServe = Encoding.UTF8.GetBytes(strMsgToServe);
            socket.SendTo(bytMsgToServe, bytMsgToServe.Length, SocketFlags.None, ipe);
            Console.WriteLine("消息已发送。。。");

            //IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            EndPoint Remote = new IPEndPoint(IPAddress.Any, 0);//(EndPoint)sender;
            bytMsgToServe = new byte[1024];
            int recv = socket.ReceiveFrom(bytMsgToServe, ref Remote);//接受来自服务器的数据

            Console.WriteLine("Message received from{0}:", Remote.ToString());
            Console.WriteLine("收到的服务端消息:"+Encoding.UTF8.GetString(bytMsgToServe, 0, recv));
            socket.Close();
            Console.ReadLine();
        }

        /// <summary>
        /// 获取本地IP地址信息
        /// </summary>
        public static string GetAddressIP()
        {
            ///获取本地的IP地址
            string AddressIP = string.Empty;
            foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
                {
                    AddressIP = _IPAddress.ToString();
                }
            }
            return AddressIP;
        }


Server端:

static void Main(string[] args)
{
int port = 2001;
string strHost = GetAddressIP();// "127.0.0.1";
//  创建终结点
IPAddress ip = IPAddress.Parse(strHost);
//  创建网络端口
IPEndPoint ipe = new IPEndPoint(ip, port);

//  创建socke,开始监听--SocketType枚举
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//  绑定端口
socket.Bind(ipe);
Console.WriteLine("等待客户端连接。。。");

//IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);//定义要发送的计算机的地址
EndPoint Remote = new IPEndPoint(IPAddress.Any, 0);//(EndPoint)(sender);

//  收到的二进制byte
byte[] bytRecv = new byte[1024];
int intBytes = socket.ReceiveFrom(bytRecv, ref Remote);//接受来自服务器的数据
//Console.WriteLine("Message received from{0}:", Remote.ToString());
Console.WriteLine("收到的信息:-"+Encoding.UTF8.GetString(bytRecv, 0, intBytes));

string welcome = "Welcome to my test server!";
bytRecv = Encoding.ASCII.GetBytes(welcome);
socket.SendTo(bytRecv, bytRecv.Length, SocketFlags.None, Remote);
Console.ReadLine();
}
/// <summary>
/// 获取本地IP地址信息
/// </summary>
public static string GetAddressIP()
{
///获取本地的IP地址
string AddressIP = string.Empty;
foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
{
if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
{
AddressIP = _IPAddress.ToString();
}
}
return AddressIP;
}


当将服务层写成window服务时,如果客户端关闭,服务端会报错,“远程主机关闭了一个现有的链接”,然后整个服务都停止了。

解决办法:为socket对象设置低级操作模式

//  为 Socket 设置低级操作模式,不然当客户端关闭的时候,会报错
uint IOC_IN = 0x80000000;
uint IOC_VENDOR = 0x18000000;
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);

另外,在window服务中,定时控件是不能用的,但是也不报错,不提醒,如果要定时循环,

解决办法:

System.Timers.Timer tmrSelectCOM = new System.Timers.Timer(2000);
tmrSelectCOM.Elapsed += new System.Timers.ElapsedEventHandler(tmrSelectCOM_Tick);
tmrSelectCOM.Enabled = true;

TCP协议:

服务端:

static void Main(string[] args)
{
//  ip地址,端口
int port = 2000;
string strIp = GetAddressIP();
//  IP对象
IPAddress ip = IPAddress.Parse(strIp);
IPEndPoint ipe = new IPEndPoint(ip, port);
//  实例化socket对象
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//  绑定端口
socket.Bind(ipe);
//  监听
socket.Listen(0);
//  为发送请求的客户端创建新的socket对象
Socket temp = socket.Accept();

//  接收消息
byte[] bytRecv = new byte[1024];
int intCount = temp.Receive(bytRecv,bytRecv.Length,0);
string strRecv = Encoding.UTF8.GetString(bytRecv, 0, intCount);
Console.WriteLine(strRecv);

//  发送消息
string strSendMsg = "来自服务端的问候。。。";
byte[] bytSendMsg = Encoding.UTF8.GetBytes(strSendMsg);
temp.Send(bytSendMsg, 0, bytSendMsg.Length, 0);
Console.WriteLine("服务端消息已发送。。。");
Console.ReadLine();
}

private static string GetAddressIP()
{
string strAddressIP = string.Empty;
foreach (IPAddress address in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
{
if (address.AddressFamily.ToString() == "InterNetwork")
{
strAddressIP = address.ToString();
}
}
return strAddressIP;
}
客户端:

public static void Main(string[] args)
{
int port = 2000;
string strIp = GetAddressIP();
//  IP对象
IPAddress ip = IPAddress.Parse(strIp);
IPEndPoint ipe = new IPEndPoint(ip, port);
//  创建socket对象
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//  连接
socket.Connect(ipe);
Console.WriteLine("已连接。。。");

//  发送信息
string strSendMsg="来自客户端的问候。。。";
byte[] bytSendMsg = Encoding.UTF8.GetBytes(strSendMsg);
socket.Send(bytSendMsg, 0, bytSendMsg.Length, SocketFlags.None);
Console.WriteLine("消息已发送。。。");
//  接收
byte[] bytRecvMsg = new byte[1024];
int intCount = socket.Receive(bytRecvMsg);
string strRecvMsg = Encoding.UTF8.GetString(bytRecvMsg, 0, intCount);
Console.WriteLine(strRecvMsg);
Console.ReadLine();
}

private static string GetAddressIP()
{
//  获取本地的IP地址
string AddressIP = string.Empty;
foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
{
if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
{
AddressIP = _IPAddress.ToString();
}
}
return AddressIP;
}

TCP图:



UDP图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: