网络编程相关知识

时间:2022-12-24 11:13:28
一、邮件传送与接收:
SMTP(简单邮件传输协议):用于邮件发送,一般客户机将邮件发送到SMTP服务主机上,SMTP主机根据传输协议将邮件发到指定地址。
POP3(邮局协议第3版):用于邮件接收,客户机登录到POP服务主机后,可以从上面下载收到的邮件。
邮箱APP开发:用C#开发中都需要引用以上两个协议类,并配置两个协议信息。


二、Socket通信(以下代码及代码错误解释都是基于C#):

(1)Socket通信同步与异步、阻塞与非阻塞:
同步:发送后必须等到对方应答完成才能继续发送,串行传输;
异步:发送后不必等到对方应答就可继续发送,并行传输。

阻塞(如:监听到连接请求前一直阻塞不继续执行)和非阻塞(如:没有监听到依然执行相关语句,不阻塞)意义上类似同步和非同步,但还是有区别的:阻塞模式表示比如发送或接受操作没有发送结束或没有接收到前,程序不会继续执行后面的代码;而非阻塞模式顾名思义是可以继续执行下面的代码。

个人观点:同步/异步和阻塞/非阻塞模式在应用中主要表现在程序内在运行模式上的不同,比如异步和非阻塞相对可以有更高的执行效率,如果不需要长时间连接且不注重程序运行效率问题,两者都可以使用。(纯属个人当前的理解,如有不对请各位前辈指出!


(2)UDP与TCP协议区别:
1、UDP和TCP协议都是传输层协议,其中TCP协议称为面向连接(可靠的)传输协议,而UDP协议称为不可靠的传输协议,因为在从发送方到接收方的传递过程中出现的数据丢失,协议本身并不能做出任何检测或者提示。
2、UDP速度比TCP快,因为UDP不需要先与对方建立连接,也不需要连接确认,因此速度要快的多。

3、UDP协议一般在非文件传输中使用,TCP/IP协议一般在不允许信息丢失的通信(入文件传输)中使用。

4、在编写socket通信中,可以将udp和tcp协议混合使用(比如:在编写类似qq聊天软件中,可以用udp协议传输文字、语音和视频传输,而用TCP协议传输文件,因为文件传输要求可靠且不丢包)。

5、混合使用TCP和UDP协议时,可以同时将两个对象都绑定到同一端口,因为两个协议是两个分开的模块,端口号虽然相同但由不同的模块分发,所以实质是不同的。具体解释见引文:http://blog.csdn.net/cwj649956781/article/details/8833234


(3)流的说明:

数据的传输都会用到流,一般的文件如文本、图片等,可以运用FileStream类来完成。对象的传输也要转换成流,只不过我们称之为对象的序列化。所以不管是文件还是内存中的对象,要实现传输都会转换成有序列的二进制数组,然后在进行传输。C#中可运用socket来完成计算机之间的数据传输。


(4)直接的Socket通信(非使用udpclient和tcpclient类)步骤如下(C#代码):
客户端:

Socket   socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建socket对象

IPEndPoint remotePoint = new IPEndPoint(IPAddress.Parse(远程IP), 8002);//远程IP和端口号

socketSend.Connect(remotePoint); //连接远程主机

byte[] buff = System.Text.Encoding.Default.GetBytes(信息));  //信息转换成字节数组

socketSend.Send(buff);  //发送数据

socketSend.Close(); //关闭Socket

服务端:

Socket socketListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //创建Socket对象

IPEndPoint hostPoint = new IPEndPoint(Dns.GetHostEntry(Dns.GetHostName()).AddressList[0], 8002); //本机IP和端口号

socketListen.Bind(hostPoint); //Socket绑定到该结点上

socketListen.Listen(50); //让Socket对象处于监听状态

while (true) //建立连接请求
{
     Socket socket = socketListen.Accept();//建立连接并返回连接的socket对象
     Thread thrAccept = new Thread(new ParameterizedThreadStart(DataProcess));
     thrAccept.Start(socket);//另一线程处理此次连接。这里也可以运用创建对象传参,线程执行对象的方法

}

public void DataProcess(object obj)//处理数据
{
      Socket socket = (Socket)obj;
      byte[] buff = new byte[1024];//创建缓存空间
      int len =socket.Receive(buff);//把接收的数据放入字节数组中
      string s = System.Text.Encoding.Default.GetString(buff, 0, len);
}


    除了直接使用Socket进行数据传输,也可以使用TcpLister类和TcpClient类、或Udpclient类进行传输。其实TcpLister和TcpClient就是Socket封装后的类,是.NET为了简化编程复杂度而对套接字又进行了封装。但是,TcpLister和TcpClient只支持标准协议编程。如果希望编写非标准协议的程序,只能使用套接字socket来实现。一般我们优先选择TcpClient或者Udpclient类进行数据传输,因为编程线对简单。

(5)使用socket通行时,无论使用TCP协议还是UDP协议,发送端(客户端)不需要绑定本地IP和端口port,调用.net framework发送数据时,就会自动选择打开一个本地IP和端口,其中端口号是随机的。接收端(服务端)需要绑定本地IP和port。如下示例(C#代码):

TCP(发送端

TcpClient client = null;

client = new TcpClient(IPStr, Port); //连接远程目标机,另一种连接方法为connect()(注:此处并非绑定本地机IP和port

NetworkStream netstream = client.GetStream(); //创建用于缓存的网络数据流

netstream.Write(SendingBuffer, 0, SendingBuffer.Length);   //写入网络缓存

//可见:上述TCP发送前并没有绑定本地主机的IP和port


TCP(监听接收端)

TcpClient receiveTcpClient = null;

Listener = new TcpListener(ip, port);   //监听本机指定IP和portN端口(也就是绑定本地端口)

Listener.Start();

receiveTcpClient = fileListener.AcceptTcpClient();   //获取远程主机对象


UDP(发送端)

UdpClient sendUdpClient =null;

sendUdpClient = new UdpClient();   //实例化,系统会自动分配随机端口给sendUdpClient(发送不需绑定本机指定IP和端口)

IPEndPoint iep = new IPEndPoint(remoteIp, portR);  //设置目标机终结点

sendUdpClient.Send(bytes, bytes.Length, iep); //向远程主机发送数据


UDP(监听接收端)

IPEndPoint local = new IPEndPoint(ip, port); 

receiveUdpClient = new UdpClient(local);   //实例化接收机的UDPClient类,并绑定本地主机IP和端口port(相当于TCP的被

   //侦听端口)

IPEndPoint remote = new IPEndPoint(IPAddress.Any,0);      //用于获取返回的发送方主机IP和端口port(经本人亲测:该终点初始化并没多大意义,仅仅是用于将receive()     //返回的远程ip及port填充进来)

byte[] receiveBytes = receiveUdpClient.Receive(ref remote);     //Receive方法将阻止,直到数据报从远程主机到达为止

说明:UDP监听端(本没有监听,暂且这样说)与TCP监听服务器不太一样:TCP服务端只需要设置监听端口即可,UDP则首先需要绑定本地端口,然后在设定用于监听的端口。
(6)IP地址环回地址:用于绕过TCP/IP协议直接向自身发送信息的地址,其中IPV4中的环回地址是{127.0.0.1},IPV6的环回地址是{0.0.0.0.0.0.0.1}(简写{::1})


(7)关于“一般套接字只允许访问一次”的错误:一般发送或接受完后需要关闭UDP或者TCP对象,从而就可释放对套接字的访问。


(8)NetworkStream(或者任何一个其它的Stram)的Read和Write操作都是连续的。也就是说,如果头一次Read读取了200个字节,第二次是从Stream的第201个字节开始读的,不是第一个。


三、线程:

1、新建的子线程在其运行结束后都会于数秒钟后自动释放;
2、线程后台运行只适合于短时间线程。
3、invoke和InvokeRequired:
InvokeRequired:C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为true时,说明有一个创建它以外的线程想访问它,那么必须使用控件的一个 Invoke 方法来将调用封送到拥有控件的线程中并以委托方式执行。
Invoke:它是控件类中的方法,必须以Control.Invoke(delegate method,object[] args)方式调用,其作用是将委托方法封装到拥有本控件的线程中执行。

4、在子线程中长时间用while(true)死循环监听socket连接请求,一般需要在死循环中加入一句thread.sleep(时间)来减少死循环频率,以减轻CPU负担。


四、委托:
1、委托一般由四部分组成:
(1)声明委托类型或者叫做委托类(必须在其他类外声明);
(2)实例化一个方法或事件名(主要有两种类型:普通的delegate委托和特殊的包含event的委托);
(3)绑定该委托方法或者事件(event委托需要使用'+=',而普通委托直接用赋值=即可,且与(2)中实例化方式息息相关),并
编写该委托方法或事件,用于处理委托内容;
(4)执行该委托(执行前一定要保证该委托已经被绑定,否则会提示:未将对象引用设置到对象实例;event委托只能实例对象所在类中进行)。
举例:
public delegate void GreetingDelegate(string name);//GreetingDelegate可以看做一个类或类型,所以要在其他类外面声明
public event GreetingDelegate MakeGreet; //包含event的委托方法
f.MakeGreet += new GreetingDelegate(f_MakeGreet);自动生成处理事件public void f_MakeGreet(string name){}//绑定

f_MakeGreet("ss");//执行


五、C#中的Xml文件操作

XML操作主要介绍四种操作:创建XML文件、添加XMLNode结点、删除XMLNode结点和读取XMLNode结点信息,一般情况下这四种就够了,代码如下:

    #region xml文档操作
//创建xml文件(格式固定的)
private void CreateXml(string FilePath, string MnodeStr, string CnodeStr, string value)
{
try
{
XmlDocument xmlDoc = new XmlDocument();
//创建类型声明节点
XmlNode node = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "");
xmlDoc.AppendChild(node);
//创建根节点
XmlNode root = xmlDoc.CreateElement("BOMConfig");
xmlDoc.AppendChild(root);
XmlNode node1 = xmlDoc.CreateElement(MnodeStr);
root.AppendChild(node1);
CreateNode(xmlDoc, node1, CnodeStr, value);
xmlDoc.Save(FilePath);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}

//添加结点
/// <summary>
/// 添加节点
/// </summary>
/// <param name="xmldoc"></param> xml文档
/// <param name="parentnode"></param>父节点
/// <param name="name"></param> 节点名
/// <param name="value"></param> 节点值
///
private void AddNode(string FilePath, string parentNodeName, string name, string value)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(FilePath);
XmlNode root = xmlDoc.SelectSingleNode("BOMConfig"); //获取根节点
foreach (XmlNode Pnode in root.ChildNodes)
{
if (Pnode.Name == parentNodeName)//遍历角色
{
CreateNode(xmlDoc, Pnode, name, value); //给角色添加权限
xmlDoc.Save(FilePath);
return;
}
}
XmlNode Pnode1 = xmlDoc.CreateElement(parentNodeName);
root.AppendChild(Pnode1);
CreateNode(xmlDoc, Pnode1, name, value);
xmlDoc.Save(FilePath);
}

private void CreateNode(XmlDocument xmlDoc, XmlNode parentNode, string name, string value)
{
XmlNode node = xmlDoc.CreateNode(XmlNodeType.Element, name, null);
node.InnerText = value;
parentNode.AppendChild(node);
}

//删除指定节点的子节点
private void DelXml(string FilePath, string nodeName)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(FilePath);
XmlNode Pxn1 = xmlDoc.SelectSingleNode("BOMConfig");
XmlNode Pxn2 = Pxn1.SelectSingleNode(nodeName); //获取角色结点
if (Pxn2 != null)
{
Pxn2.RemoveAll();
}
xmlDoc.Save(FilePath);
}

//将权限值读取并赋给界面显示
private void ReadNode(string FilePath,string deptStr)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(FilePath);
XmlNode root = xmlDoc.SelectSingleNode("BOMConfig"); //获取根节点
XmlNode node = root.SelectSingleNode(deptStr); //获取角色
if (node != null)
{
for (int i = 0; i < M_TypeList.Items.Count; i++)
{
if (node.SelectSingleNode(M_TypeList.Items[i].ToString()) != null)
{
bool value = true;
if (node.SelectSingleNode(M_TypeList.Items[i].ToString()).InnerText == "true")
value = true;
else if (node.SelectSingleNode(M_TypeList.Items[i].ToString()).InnerText == "false")
value = false;
else
continue;
M_TypeList.SetItemChecked(i, value);
}
else //不存在代表没有权限
{
M_TypeList.SetItemChecked(i, false);
}
}
}
}
#endregion

以上对xml文档的操作方法可以完成大部分任务,但是在读写xml文档时需要注意:xml文档不可以包括部分非法字符,如:空格,<,>,括号,等。



六、ASP.NET开发

1、ASP.NET网站开发先关知识:

(1)HTTP协议下的网页代码有三种模式:流模式(以<%   %>开头结尾)、脚本模式(<script   script>开头结尾)和页面与代码分离模式(即将个人代码与自动生成代码放在不同的文件夹),当前ASP.NET 2.0以后都是采用代码分离模式。


/***********************************以下部分不再完全基于C#,具体会有说明************************************/

七、网络编程中常用的应用程序ping

1、PING (Packet Internet Groper),因特网包探索器,用于测试网络连接量的程序。Ping发送一个ICMP(Internet Control Messages Protocol)即因特网信报控制协议;回声请求消息给目的地并报告是否收到所希望的ICMP echo (ICMP回声应答)。

它是用来检查网络是否通畅或者网络连接速度的命令。它所利用的原理是这样的:利用网络上机器IP地址的唯一性,给目标IP地址发送一个数据包,再要求对方返回一个同样大小的数据包来确定两台网络机器是否连接相通,时延是多少。


八、http协议的网络跳转状态码解释

答:如下:

1xx(临时响应) 2xx(成功) 3xx(已重定向)     301 永久重定向     302 临时重定向 4xx(请求错误)     404 找不到网页(网址URL错误)     403 已禁止     401 未授权     400 请求失败;服务器不理解请求语法50X(后台错误,一般是web代码问题)