精华内容
下载资源
问答
  • 网络编程技术
    千次阅读
    2020-03-05 20:06:00

    网络编程技术简介

    什么是网络编程???

    网络编程从大的方面说就是对信息的发送到接收,中间传输为物理线路的作用。
    网络编程最主要的工作就是在发送端把信息通过规定好的协议进行组装包,在接收端按照规定好的协议把包进行解析,从而提取出对应的信息,达到通信的目的。

    ​ 网络编程的本质是两个设备之间的数据交换。其实就是把一个设备中的数据发送给另外一个设备,然后接受那个设备反馈的数据。比如C/S 和B/S架构,都体现了这种关系,都是基本上都是请求响应式的。不过模式有些不同。而我们做的就是基于网络通信的原理,编写这种网络应用程序。

    传统的网络编程技术简介

    ​ 网络编程的技术还要从套接字说起,Unix系统把主机+端口,叫做**“套字”(socket)**。套接字是支持TCP/IP网络通信的基本操作单元。有了它,就可以进行网络应用程序开发了。 image-20200305194302534

    ​ 一个套接字实例中保存有本机的IP地址和端口 对方的IP地址和端口 双方通信采用的网络协议等信息。

    NET传统网络编程

    • .System.Net命名空间中提供了一组Socket类调用WinSocket
    • 针对TCP、UDP、FTP等协议对Socket类再次封装,提供
      • TCPCLIENT、TCPLISTENER、 UDPCLIENT
      • FTP应用编程、SMTP应用编程

    WCF编程技术

    ​ 基于传统网络编程技术

    套接字编程(Socket类)

    套接字有3种不同的类型

    • 流式套接字:实现面向连接的TCP通信
    • 数据报套接字:实现无连接的UDP通信
    • 原始套接字:实现IP数据包通信,实现自定义协议通信

    特点

    • 可控性强。
    • 灵活,可实现自定义网络协议。
    • 代码编写复杂

    TCP应用编程(TcpClient类、TcpListener类)

    TCP通信

    • 面向连接通信
    • 可靠的数据传输

    TCP实现方法

    • Socket类面向连接的套接字
    • 服务端使用TcpListener类客户端使用TcpClient类

    UDP应用编程(UdpClient类)

    UDP通信

    • 无连接的套接字

    • 无连接的套接字不需要在网络设备之间发送连接信息。

    实现方法:

    • UdpClient类:

    • 在UDP层面对套接字编程的进一步封装

    • Socket无连接套接字

    参考资料:

    [1] 网络编程

    更多相关内容
  • C#网络编程技术教程

    2017-11-03 14:21:10
    C#网络编程技术教程,包含各种C# ftp webservice http socket
  • Visual C#网络编程技术与实践

    热门讨论 2013-03-18 19:50:31
    《VISUAL C# 网络编程技术与实践》详细介绍了利用Visual C# 2005进行网络编程的方法和技巧。全书共分13章,主要内容包括网络编程原理、Visual C# 2005的套接字以及多线程的开发、基于各种不同协议的网络编程应用模块...
  • C#网络编程技术教程\

    2010-12-22 13:12:08
    C#网络编程技术教程rC#网络编程技术教程
  • 游戏中的网络编程技术及应用.pdf

    热门讨论 2014-09-13 13:04:55
    游戏中的网络编程技术及应用 对游戏好用
  • windows 网络编程技术

    热门讨论 2010-07-15 10:52:33
    WINDOWS网络编程技术.rar,WINDOWS网络编程技术,016.PDF,014.PDF,007.PDF,011.PDF,005.PDF,008.PDF,013.PDF,012.PDF,015.PDF,009.PDF,内容简介.TXT,001.PDF,003.PDF,019.PDF,006.PDF,002.PDF,目录.TXT,010.PDF,018....
  • PHP网络编程技术详解 完整版 pdf + 源码
  • 《TCP IP网络编程

    热门讨论 2015-06-02 22:23:10
    《TCP/IP网络编程》针对网络编程初学者,面向具备C 语言基础的套接字网络编程学习者,适合所有希望学习Linux和Windows 网络编程的人。 第一部分主要介绍网络编程基础知识。此部分主要论述Windows和Linux平台网络编程...
  • 此书对学习windows网络编程的爱好者,程序员真的是一布经典书
  • 计算机网络高级软件编程技术 源代码
  • Socket网络编程

    千次阅读 2022-04-07 18:47:23
    Socket 1 环境查看 通过cmd窗口的命令:ipconfig查看本机IP地址 查看网络情况是否正常:ping百度官网 用来进行本地测试的地址 127.0.0.1,回环测试地址,默认代表的就是本机的IP ...Socket就是为网络编程提供的一

    Socket

    1 环境查看

    1. 通过cmd窗口的命令:ipconfig查看本机IP地址
      查看IP地址
    2. 查看网络情况是否正常:ping百度官网
      查看网络情况

    用来进行本地测试的地址 127.0.0.1,回环测试地址,默认代表的就是本机的IP

    2 Socket概述

    socket编程也叫套接字编程,应用程序可以通过它发送或者接受数据,可对其像打开文件一样打开/关闭/读写等操作.
    套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信.
    网络套接字是IP地址与端口号TCP协议的组合
    Socket就是为网络编程提供的一种机制,通信的两端都有Socket
    网络通信其实就是Socket之间的通信,数据在两个Socket之间通过I/O进行传输.
    

    通信模式
    TCP网络通信模型

    3 服务器端

    3.1 ServerSocket

    在服务器端选择一个端口号,在指定端口上等待客户端发起连接

    构造方法:
    ServerSocket(int port) 创建绑定到特定端口的服务器套接字
    常用方法:
    Socket accept() 侦听并接收到此套接字的连接
    void close() 关闭此套接字
    启动服务:
    ServerSocket ss = new ServerSocket(端口号);
    等待客户端发起连接,连接后会建立起通道:Socket socket = ss.accept();

    4 客户端Socket

    我们经常使用的就是客户端

    构造方法:
    Socket(String host,int port) 创建一个流套接字,并将其连接到指定主机上的指定端口号
    常用方法:
    InputStream getInputStream() 返回此套接字的输入流
    OutputStream getOutputStream() 返回此套接字的输出流
    void close() 关闭此套接字
    新建Socket对象,连接指定IP指定的端口
    Socket s = new Socket(IP,port);
    从Socket获取双向的流:
    InputStream in = s.getInputStream();
    OutputStream out = s.getOutputStream();

    5 入门案例

    5.1服务器端代码编写

    需求: 服务器端接收客户端发来的数据”hello”,并且给客户端响应数据”world”

    创建包: cn.tedu.net
    创建类: Server.java

    package cn.tedu.net;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    /**本类用来表示Socket网络编程案例的服务器端
     * 完成步骤分析:
     * 1.启动服务器
     * 2.接收客户端的连接请求
     * 3.接收客户端发来的数据
     * */
    /**测试注意事项:先启动服务器端,再启动客户端*/
    public class Server {
    	public static void main(String[] args) throws Exception {
    		//1.启动服务器,指定端口号为8888,等待客户端的连接
    		/**注意:
    		 * 1.使用ServerSocket需要导包java.net.ServerSocket
    		 * 2.此操作会抛出异常
    		 * 3.指定的端口号范围是:0-655535,而0-1024是系统端口号,不能指定
    		 * */
    		ServerSocket ss = new ServerSocket(8888);
    		//2.接收客户端的连接请求,并建立数据通信通道
    		Socket socket = ss.accept();
    		//3.获取到读取流,接收并读取客户端发来的数据
    		InputStream in = socket.getInputStream();
    		//通过循环挨个读取显示读到的内容
    		for(int i = 0;i < 5;i++) {
    			//int b = in.read();//此方法读取的结果是把字符转成数字
    			char c = (char) in.read();//为了直接显示读取到的字符,需要强制类型转换(大转小,int转char)
    			System.out.print(c);//print()同行输出,注意细节哦
    		}
    		//5.给客户端发送数据
    		OutputStream out = socket.getOutputStream();
    		out.write("world".getBytes());
    		out.flush();
    		
    		//4.释放资源
    		/**注意关流的顺序,后出现的先关闭*/
    		in.close();
    		ss.close();
    	}
    }
    

    5.2 客户端代码编写

    创建包: cn.tedu.net
    创建类: Client.java

    package cn.tedu.net;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    /**本类用来表示Socket网络编程案例的客户端
     * 完成步骤分析:
     * 1.指定要连接的服务器
     * 2.给服务器发送hello
     * */
    public class Client {
    	public static void main(String[] args) throws Exception {
    		//1.指定要连接的服务器,需要同时指定服务器的IP & Port
    		/**注意:
    		 * 1.使用Socket需要导包java.net.Socket
    		 * 2.此操作会抛出异常
    		 * 3.如果使用的是本机的IP,地址是固定值,用来测试时使用127.0.0.1
    		 * */
    		Socket socket = new Socket("127.0.0.1",8888);
    		//2.给服务器端发送hello
    		OutputStream out = socket.getOutputStream();
    		//把要输出的数据hello字符串转变成byte[]的形式进行输出
    		out.write("hello".getBytes());
    		out.flush();
    		
    		//4.读取从服务器端返回的数据
    		InputStream in = socket.getInputStream();
    		for (int i = 0; i < 5; i++) {
    			char c = (char) in.read();//为了显示字符而不是数字,强制类型转换成char
    			System.out.print(c);//不换行展示获取到的数据
    		}
    		
    		//3.释放资源
    		//out.close();
    		socket.close();
    		
    	}
    }
    

    5.3 测试注意事项:

    1.测试顺序:先启动服务器端,再启动客户端
    2.可以打开多个控制台显示窗口,方便查看
    3.可以将其中一个控制台显示窗口固定,否则多个窗口的显示内容是一样的
    4.注意每次测试完毕后,都需要将之前的控制台窗口都关闭后再次进行新一轮的测试
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    注意:要先启动服务器端再启动客户端,否则会报错,如下所示:

    在这里插入图片描述

    注意,下次测试的时候,把上次测试的窗口都关掉,重复启动多次,正在使用,新次测试就无法使用

    在这里插入图片描述

    6 服务器端线程模型

    入门案例中,存在两种阻塞状态:

    1. 服务器端的accept()一直在等待客户端的连接
    2. 通信中的read()死等数据
      在这里插入图片描述

    7 读一行写一行案例

    创建包: cn.tedu.net
    创建类: TestIO.java

    package cn.tedu.net;
    
    import java.io.BufferedReader;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    /**这个类用来测试一行一行读取,一行一行写出*/
    public class TestIO {
    	public static void main(String[] args) {
    		//method();//初步测试readLine()
    		method2();//改进
    	}
    	public static void method2() {
    		BufferedReader in = null;
    		PrintWriter out = null;
    		try {
    			//1.读取一行数据,先拿到读取数据的流,注意文件需要自己在win创建
    			in = new BufferedReader(new FileReader("D:\b.txt"));
    			//2.定义变量,记录每行读取到的数据
    			String line;
    			//3.设置循环读取数据,只要有数据就一直读取
    			while( (line=in.readLine()) != null) {
    				System.out.println(line);
    			}
    			
    			//4.一行行写出数据:PrintWriter
    			out = new PrintWriter(new FileWriter("D:\b.txt"));
    			out.println("java");
    			out.println("hello");
    			out.flush();//为了防止有数据没有发送过去,可以刷一下
    		} catch (Exception e) {
    			e.printStackTrace();
    		}finally {
    			try {
    				//5.释放资源
    				out.close();
    				in.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    	public static void method() {
    		try {
    			//1.读取一行数据,先拿到读取数据的流,注意文件需要自己在win创建
    			BufferedReader in = new BufferedReader(new FileReader("D:\b.txt"));
    			//2.调用readLine方法进行测试
    			String line = in.readLine();
    			String line2 = in.readLine();
    			String line3 = in.readLine();
    			//测试1:b.txt没有数据时,readLine()返回null
    			//测试2:b.txt有数据,而且是1整行数据,readLine()可以返回整行全部数据
    			//测试3:b.txt有数据,而且是多行数据,readLine()只可以返回第1行全部数据
    			/**原因:readLine()在读取数据时,会读取特殊标记,换行符
    ,读到换行符就结束
    			 * 结论:readLine()只可以读取1整行数据,如果是多行数据,需要多次调用
    			 * */
    			//3.打印测试结果
    			System.out.println(line);
    			System.out.println(line2);
    			System.out.println(line3);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    

    8 拓展 : 回声案例

    需求:接收客户端输入的每行数据,服务器再把回应给到用户

    8.1 服务器端

    接收客户端输入的每行数据,服务器再把回应给到用户

    创建包: cn.tedu.net
    创建类: Server2.java

    package cn.tedu.net;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Scanner;
    
    /**这个类用来当做回声案例的服务器端
     * 1.启动服务器
     * 2.接收客户端的连接请求
     * 3.给每个用户分配对应的话务员
     * 4.话务员:主要负责和对应的客户端对象进行沟通I/O
     * */
    /**1.创建优化后的Server2类,充当服务器端*/
    public class Server2 {
    	/**2.创建方法,负责服务多个客户*/
    	public void service() {
    		/**3.匿名对象+匿名内部类(重写run方法)*/
    		new Thread() {
    			/**5.把业务写在run()中*/
    			@Override
    			public void run() {
    				try {
    					//5.1 启动服务器,设置端口号为8000并等待客户端连接
    					ServerSocket ss = new ServerSocket(8000);
    					System.out.println("服务器启动成功!");
    					while(true) {//死循环,一直accept,也就是接受客户端的连接请求
    						//5.2 一直接受所有客户端的连接请求
    						Socket socket = ss.accept();
    						System.out.println("客户端连接成功!");
    						//5.3 给每个客户分配自己对应的话务员,1v1
    						HuaWuThread t = new HuaWuThread(socket);
    						t.start();
    					}
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    				
    			};
    		}.start();/**4.启动线程*/
    	}
    	
    	/**6.创建话务员内部类,主要负责和客户端沟通 I/O*/
    	class HuaWuThread extends Thread{
    		//6.1 定义本类中的成员变量socket,用来保持通话
    		Socket socket;
    		//6.2含参构造,接受当前的连接信息,保持通话,为谁服务就保存谁的数据
    		public HuaWuThread(Socket socket) {
    			this.socket = socket;
    		}
    		//6.3把话务员的业务放在run(),一直读取客户端发来的数据,并作出回应
    		@Override
    		public void run() {
    			try {
    				//7.1读取一行BufferedReader,并且写出一行PrintWriter --双向流
    				BufferedReader in = new BufferedReader(
    						new InputStreamReader(socket.getInputStream()));
    				PrintWriter out = new PrintWriter(
    						new OutputStreamWriter(socket.getOutputStream()));
    				//7.2读取客户端发来的一行数据
    				String line;//定义变量,记录读取到的一行数据
    				while((line = in.readLine()) != null) {//只要有数据就一直读
    					System.out.println("客户端发来的数据:"+line);
    					//7.1可以给客户端作出响应-接收键盘输入的响应
    					System.out.println("请输入您的回应:");
    					String input = new Scanner(System.in).nextLine();
    					//7.2发出作为服务器的响应
    					out.println(input);
    					out.flush();//把数据刷出去
    				}
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    	
    	public static void main(String[] args) {
    		Server2 s = new Server2();
    		s.service();
    	}
    }
    

    8.2 客户端

    接收客户端输入的每行数据,服务器再把回应给到用户

    创建包: cn.tedu.net
    创建类:Client2.java

    package cn.tedu.net;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.util.Scanner;
    
    /**本类用来做回声案例的客户端
     * 1.连接指定的服务器
     * 2.给服务器发送数据
     * 3.接收服务器响应的数据
     * */
    public class Client2 {
    	public static void main(String[] args) {
    		try {
    			//1.连接指定的服务器,同时指定服务器的IP和端口号
    			Socket socket = new Socket("127.0.0.1",8000);
    			//2.给服务器发送数据
    			while(true) {
    				//向服务器写出一行数据,并且读取服务器响应回来的数据
    				PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
    				BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    				//3.通过流对象进行发送和读取的操作
    				System.out.println("请输入您想给服务器发送的数据:");
    				String input = new Scanner(System.in).nextLine();
    				out.println(input);//向服务端发送指定数据
    				out.flush();//把数据刷出去
    				String line = in.readLine();//读取回声数据
    				System.out.println("服务器端响应的数据是:"+line);
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    
    展开全文
  • visual c++网络通信编程技术详解

    热门讨论 2014-06-06 14:53:52
    visual c++网络通信编程技术详解 代勇李伟 相关课件
  • C/C++网络编程详解(Windows版)

    千次阅读 多人点赞 2022-03-25 19:16:31
    简析一个最简单的服务器和客户端怎么写,以及相关网络函数的常用方法


    教程推荐:

    人工智能教程,点击这里查看,通俗易懂,风趣幽默

    C/C++教程,点击这里查看,以项目为主导从入门到精通

    前言

    相比于基础,网络编程就要复杂一些,但其实也有固定格式,记住即可。

    需要的头文件和库:

    #include<WinSock2.h>
    #pragma comment(lib,"ws2_32.lib")
    

    一、服务器

    主要流程及主要函数:

    1. 网络环境初始化:WSAStartup
    2. 创建服务器套接字:socket
    3. 绑定本机IP和端口:bind
    4. 监听客户端:listen
    5. 等待客户端连接:accept
    6. 发送消息:send
    7. 接收消息:recv
    8. 关闭socket:closesocket
    9. 清除网络环境:WSACleanup

    WSAStartup函数

    正常使用

    函数原型:

    int WSAStartup(
    WORD wVersionRequested, //版本号,使用MAKEWORD宏生成
    LPWSADATA lpWSAData //数据
    );
    //返回值:0代表成功,否则失败
    

    使用方法:

    #include<WinSock2.h>
    #include<iostream>
    #pragma comment(lib,"ws2_32")
    using namespace std;
    int main() {
    	WSADATA data;
    	int ret=WSAStartup(MAKEWORD(2,2),&data);
    	if (ret) {
    		cout << "初始化网络错误!" << endl;
    		return -1;
    	}
    }
    

    该函数用于初始化网络环境,参数基本上是固定写法,记住即可,必须要有。

    函数详解

    该函数实则是用来加载Windows Socket动态库的

    wVersionRequested参数用来指定准备加载动态库的版本号,高字节为库文件的副版本,低字节指定主版本,MAKEWORD(X,Y)宏用于生成该参数,其中X为高字节,Y为低字节

    lpWSAData 为指向WSADATA结构体的指针,该参数用于返回被加载动态库的有关信息

    typedef struct WSAData {
    WORD  			wVersion; //期望调用者使用的socket版本(或实际返回的socket版本,可根据此参数判断返回的版本号是否正确,可通过HIBYTE宏取得高字节,LOBYTE宏取得低字节)
    WORD  			wHighVersion; //本机Dll支持的最高版本
    unsigned short  iMaxSockets;//一个进程最多可以打开的套接字数量(2.0版本后忽略此值)
    unsigned short  iMaxUdpDg; //一个进程发送或接收的最大数据报长度
    char FAR *   	lpVendorInfo; //厂商专有信息(2.0版本后忽略此值)
    char    		szDescription[WSADESCRIPTION_LEN+1]; //DLL的描述信息
    char    		szSystemStatus[WSASYS_STATUS_LEN+1];//DLL的状态信息
    

    socket函数

    函数原型:

    SOCKET socket(
    int af,	//地址类型,常用IPv4地址:AF_INET,和IPv6地址:AF_INET6
    int type, //套接字类型,常用TCP协议:SOCK_STREAM,UDP协议:SOCK_DGRAM
    int protocol //协议类型,一般填0,自动选择即可
    );
    //返回值,INVALID_SOCKET失败,该宏实则定义为-1,否则成功
    

    使用:

    
    SOCKET sock=socket(AF_INET,SOCK_STREAM,0);
    if (sock == -1) {
    	cout << "创建套接字失败";
    	return -1;
    }
    
    

    该代码创建了IPv4类型的地址,TCP协议的套接字

    完整视图:
    在这里插入图片描述

    bind函数

    函数原型:

    int bind( 
    SOCKET s, //创建的socket
    sockaddr * name, //包含地址和端口的结构体
    int namelen //sockaddr 结构长度
    );
    //返回值:返回SOCKET_ERROR失败,该宏被定义为-1,否则成功,返回值为0
    

    使用:

    #define _WINSOCK_DEPRECATED_NO_WARNINGS //vs环境下必须定义,否则无法使用inet_addr函数
    sockaddr_in addr;
    addr.sin_family = AF_INET; //地址为IPv4协议
    addr.sin_port = htons(9999); //端口为9999
    addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //具体绑定本机的地址
    ret=bind(sock,(sockaddr*)&addr, sizeof(addr)); //绑定
    if (ret == -1) {
    	cout << "绑定地址端口失败";
    	return -1;
    }
    

    完整视图:
    在这里插入图片描述

    listen函数

    函数原型:

    int listen(
    SOCKET s, //要监听的socket
    int backlog //等待连接的最大队列长度
    );
    //返回值:返回SOCKET_ERROR失败,该宏被定义为-1,否则成功,返回值为0
    

    使用:

    ret=listen(sock,5);
    if (ret == -1) {
    	cout << "监听套接字失败";
    	return -1;
    }
    

    完成代码:
    在这里插入图片描述

    accept函数

    函数原型:

    SOCKET accept(
    SOCKET s, //接收的socket
    sockaddr* addr, //接收到客户端的地址信息
    int * addrlen //地址信息长度
    );
    //返回值:返回INVALID_SOCKET失败,该宏定义为-1,否则成功返回客户端的套接字,可进行发送和接收消息
    

    使用:

    sockaddr addrCli;
    int len = sizeof(addrCli);
    SOCKET sockCli=accept(sock,&addrCli,&len);
    if (sockCli == -1) {
    	cout << "接收客户端连接失败";
    	return -1;
    }
    

    完整代码视图:
    在这里插入图片描述

    send函数

    函数原型:

    int send(
    SOCKET s,
    char * buf,//要发送的内容
    int len, //内容长度
    int flags //一般为0,拷贝到程序中就立即删除内核中的数据,或MSG_DONTROUTE:要求传输层不要将数据路由出去,MSG_OOB:标志数据应该被带外发送
    );
    //返回值:-1(或宏SOCKET_ERROR)表示发送失败,否则返回发送成功的字节数
    

    使用:

    char buf[0xFF] = "我是服务器";
    ret=send(sockCli, buf, strlen(buf),0);
    if (ret == -1) {
    	cout << "发送信息失败";
    }
    

    整体视图:
    在这里插入图片描述

    recv函数

    函数原型:

    int recv(
    SOCKET s, //套接字
     char * buf, //接受数据的缓存区
    int len, //缓存区大小
    int flags //标志,一般填0,将消息拷贝到应用程序中,将内核中的数据删除,还可以填MSG_PEEK,只取数据,不从内核中删除数据,MSG_OOB:处理带外数据
    );
    //返回值:小于等于0都表示出错,大于0则表示接收成功的数据大小
    

    使用:

    ret=recv(sockCli,buf,0xFF,0);
    if (ret <= 0) {
    	cout << "接受客户端数据失败";
    	return -1;
    }
    

    完整视图:
    在这里插入图片描述

    closesocket函数

    int closesocket(
    SOCKET s //要关闭的socket
    );
    

    该函数就是关闭不用的socket,释放资源

    WSACleanup函数

    无任何参数,直接调用即可

    WSACleanup();
    

    按理说尽量在应用程序退出时都要进行清理,否则下次启动可能出现错误

    修改后的代码视图:
    在这里插入图片描述
    完整代码:

    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    #include<WinSock2.h>
    #pragma comment(lib,"ws2_32")
    #include<iostream>
    using namespace std;
    int main() {
    	WSADATA data;
    	int ret=WSAStartup(MAKEWORD(2,2),&data);
    	if (ret) {
    		cout << "初始化网络错误!" << endl;
    		WSACleanup();
    		return -1;
    	}
    	SOCKET sock=socket(AF_INET,SOCK_STREAM,0);
    	if (sock == -1) {
    		cout << "创建套接字失败";
    		WSACleanup();
    		return -1;
    	}
    	sockaddr_in addr;
    	addr.sin_family = AF_INET;
    	addr.sin_port = htons(9999);
    	addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    	ret=bind(sock,(sockaddr*)&addr, sizeof(addr));
    	if (ret == -1) {
    		cout << "绑定地址端口失败";
    		WSACleanup();
    		return -1;
    	}
    	ret=listen(sock,5);
    	if (ret == -1) {
    		cout << "监听套接字失败";
    		WSACleanup();
    		return -1;
    	}
    	sockaddr addrCli;
    	int len = sizeof(addrCli);
    	SOCKET sockCli=accept(sock,&addrCli,&len);
    	if (sockCli == -1) {
    		cout << "接收客户端连接失败";
    		WSACleanup();
    		return -1;
    	}
    	char buf[0xFF] = "我是服务器";
    	ret=send(sockCli, buf, strlen(buf),0);
    	if (ret == -1) {
    		cout << "发送信息失败";
    		WSACleanup();
    		return -1;
    	}
    	ret=recv(sockCli,buf,0xFF,0);
    	if (ret <= 0) {
    		cout << "接受客户端数据失败";
    		WSACleanup();
    		return -1;
    	}
    	WSACleanup();
    }
    

    至此,一个最简单的windows服务器就写好了,可以简单执行一次发送数据和一次接受数据。

    二、客户端

    主要流程和函数:

    1. 初始化网络环境:WSAStartup
    2. 创建套接字:socket
    3. 连接服务器:connect
    4. 发送数据:send
    5. 接收数据:recv
    6. 清理网络环境:WSACleanup

    其它三个函数与服务器一样,只是多出个connect函数,使用方法也与bind函数类似

    connect函数

    函数原型:

    int connect(
    SOCKET s, //与服务器连接的socket
    sockaddr* name, //服务器的地址端口
    int namelen //上个参数结构体的长度
    );
    //返回值:-1失败,否则成功
    

    使用方法:

    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(9999);
    addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    int ret = connect(sock, (sockaddr*)&addr, sizeof(addr));
    if (ret == -1) {
    	cout << "连接服务器失败" << endl;
    	return -1;
    }
    

    完整代码视图:
    在这里插入图片描述
    完整代码:

    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    #include<WinSock2.h>
    #include<iostream>
    #pragma comment(lib,"ws2_32.lib")
    using namespace std;
    int main() {
    	WSADATA data;
    	int ret = WSAStartup(MAKEWORD(2, 2), &data);
    	if (ret) {
    		cout << "初始化网络错误!" << endl;
    		WSACleanup();
    		return -1;
    	}
    	SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    	sockaddr_in addr;
    	addr.sin_family = AF_INET;
    	addr.sin_port = htons(9999);
    	addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    	int ret = connect(sock, (sockaddr*)&addr, sizeof(addr));
    	if (ret == -1) {
    		WSACleanup();
    		cout << "连接服务器失败" << endl;
    		return -1;
    	}
    	char buf[0xFF];
    	ret=recv(sock,buf,sizeof(buf),0);
    	if (ret <= 0) {
    		WSACleanup();
    		cout << "接收服务器数据失败" << endl;
    		return -1;
    	}
    	cout << "服务器:" << buf << endl;
    
    	ret=send(sock,buf,ret,0); //将接收到的数据发回服务器
    	if (ret <= 0) {
    		WSACleanup();
    		cout << "发送服务器数据失败" << endl;
    		return -1;
    	}
    	WSACleanup();
    }
    
    

    三、其它网络相关函数

    htons,ntohs等

    这种函数名有固定的意义:

    • h:home
    • n:network
    • s:short
    • l:long

    htons:意思就是本机字节序转到网络字节序,short类型的长度
    ntohs:意思就是网络字节序转到本机字节序,short类型的长度

    还有htonl,htonll,htonf等也是类似的意思

    inet_addr,inet_ntoa

    • inet_addr:负责将我们平时看到的网络地址127.0.0.1等转化为网络字节序
    • inet_ntoa:负责将网络字节序还原为我们平时看到的字符串127.0.0.1等

    使用方法:

    sockaddr_in addr;
    addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //将127.0.0.1转换为网络字节序
    char* c_IP = inet_ntoa(addr.sin_addr);//将网络字节序转换为127.0.0.1字符串
    

    gethostbyname

    通过域名获取ip地址,比如我们常见的www.baidu.com的ip地址是多少呢?就可以通过这个函数获取

    使用方法:

    //获取主机ip
    HOSTENT* host = gethostbyname("www.baidu.com"); //如获取网站IP地址,参数填写域名即可,不需加"http://"
    if (host == NULL)
    {
    	return false;
    }
    //转化为char*并拷贝返回
    cout << inet_ntoa(*(in_addr*)*host->h_addr_list);
    

    注意事项

    这些函数都被微软定为不安全函数,想正常使用就必须在代码最前面定义宏:

    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    
    展开全文
  • linux网络编程(一)

    千次阅读 2022-04-06 07:59:34
    linux使用的网络模型是TCP/UP四层网络模型,主要由应用程序、传输层、网络层、网络接口层组成。与OSI七层模型不同,但是又相互对应,它们之间关系如下图: OSI模型的应用层、表示层、会话层对应着TCP/IP模型的应用...

    1、linux的网络模型

    linux使用的网络模型是TCP/UP四层网络模型,主要由应用程序、传输层、网络层、网络接口层组成。与OSI七层模型不同,但是又相互对应,它们之间关系如下图:

    OSI模型的应用层、表示层、会话层对应着TCP/IP模型的应用层,传输层对应传输层,网络层对应网络互连层,数据链路层和物理层对应主机到网络层(网络接口层)。linux中的网卡驱动属于7层模型中的数据链路层,属于四层模型中的最底层的网络接口层。

    2、linux网络协议栈包含的网络协议

    linux用到的网络协议主要有:TCP、IP、UDP、以太网协议等。这些协议之间的关系,体现在各类协议数据包之间的关系,主要是各类数据包之间的相互包含。如下图所示

    TCP数据包加上IP首部之后,称为IP数据报,IP数据报加上以太网首部,以太网尾部成为以太网帧。网络上传输的所有数据都是以太网帧的形式。这部分了解的很浅,详细点的可以看下面两篇文章:

    http://www.cnblogs.com/BlueTzar/articles/811160.html

    http://www.2cto.com/net/201310/252965.html

    3、linux的网络编程模型

    linux采用统一的网络编程模型:利用Socket(套接字)抽象层进行网络编程。如果不采用统一的编程模型,那么linux的网络编程会是下图的情况:

    当不同的用户进程,想要使用不同的网络协议来传输数据时,就必须调用不同协议对应的方法。比如可能进程a要调用tcp_send方法。进程b要调用ip_send方法,而进程c却要调用udp_send方法。这样,实际网络编程会变得很不方便。

    当有了统一编程模型后,linux的网络编程就是下图的情况:

    用户程序只需要调用socket抽象层提供的统一接口即可,无需考虑具体要使用哪个协议,这些事情内核会帮我们解决,我们只要调用socket抽象层提供的接口就行。这样,进程a、b、c都只要调用send方法就OK。这就使linux网络编程变得很方便了。socket又叫套接字编程模型。

    3、TCP编程模型

    TCP是一种基于连接的协议。TCP编程模型有服务器和客户机两部分,如下图:

    服务器要做的事:创建套接字、绑定地址、监听端口、等待连接、发/收数据、结束连接

    客户端要做的事:创建套接字、连接服务器、发/收数据、结束连接

    在上述模型中,填上具体的函数之后,模型如下图:

    (图片来源:http://blog.chinaunix.net/uid-9112803-id-3199813.html)

    实际编程时,只要按照上述模型,在程序中完成相应的步骤就行。具体如何实现,可以看linux网络编程(二)——TCP编程,连接如下

    http://blog.csdn.net/andoubi/article/details/51778988

    展开全文
  • C#从入门到精通(第4版) 第23章 网络编程技术 ( 视频讲解:72分钟 ) 随着社会的快速发展,互联网正渐渐普及到全民的日常生活当中,网络已经逐渐成为人们工作和生活中必不可少的一部分。C#作为一种编程语言,它...
  • 第17章 网络编程技术

    2020-03-18 15:43:47
    第17章 网络编程技术 现在互联网已经成为了我们日常生活、学习必不可少的部分,因此,网络编程也成为应用程序开发的重要领域。本章将详细介绍在Visual C++6.0环境下开发各种网络应用程序的知识。 本章内容 认识...
  • java中的网络编程

    千次阅读 2022-04-22 22:20:36
    java网络编程和发射机制
  • windows C++ 网络编程

    万次阅读 多人点赞 2019-06-10 21:16:24
    应用程序通过socket向网络发出请求或者回应。 sockets(套接字)编程有三种,流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);前两种较常用。基于TCP的socket编程是采用的流式套接...
  • 什么是网络编程(一)

    万次阅读 多人点赞 2018-12-30 00:12:26
    1.什么是网络、计算机网络的构成是什么?  在计算领域中,网络是传输信息、接受、...网络编程从大的方面就是说对信息的发送接收。 通过操作相应API调度计算机资源硬件,并且利用管道(网线)进行数据交互的过程。...
  • .NET网络高级编程

    2016-05-10 14:39:40
    网络编程是.NET企业级应用程序开发的重要内容,也是开发...本书适合那些熟悉C#基础编程知识、并希望切实掌握.NET网络编程技术的各类开发人员;本书并不要求您先前了解网络,但具有网络编程的相关知识有利于学习本书。
  • linux网络编程(完整版)

    万次阅读 多人点赞 2019-03-29 17:02:46
    之间在网上看到很多网络编程都是一个一个demo,今天我把之前学到的汇总起来,希望大家可以进行补充。 线程中我使用过两种方式编程,一种是经典函数式编程加上标志位,如下: while(1) { server_init(); ...
  • 网络安全编程技术与实例.pdf

    热门讨论 2013-05-20 08:44:47
    网络安全编程技术与实例.pdf( 网络安全编程技术与实例.pdf )
  • 计算机网络高级软件编程技术(第二版)
  • JXTA-Java P2P网络编程技术(PDF)

    热门讨论 2007-01-31 10:09:44
    JXTA是美国sun公司在JAVA领域里推出的新技术,目的是为P2P(peer-to-peer)的网络应用开发提供一个统一的平台 而贝为了鼓励和支持该技术的发展,JxTA项目采用了开放源代码的方式进行.吸引了大量业界人士参与到JXTA...
  • 本光盘为《计算机网络高级软件编程技术》的配书光盘,内容包括书中所有编程训练的参考答案与完成编程所需要的背景知识、工具与参考资料。 本光盘程序包括代码和可执行文件,部分程序不提供完整代码。
  • 这篇文章将带着大家来学习《Windows黑客编程技术详解》,其作者是甘迪文老师,推荐大家购买来学习。作者将采用实际编程和图文结合的方式进行分享,并且会进一步补充相关知识点。第六篇文章主要介绍木马病毒提权技术...
  • C#网络编程技术教程pdf 文档分享

    千次阅读 2014-01-25 10:04:47
    《C#网络编程技术教程》是一本系统介绍C#网络编程技术的教材,《C#网络编程技术教程》共11章,由两部分组成。第1部分(第1~5章)为基础知识,内容包括Visual C#.NET集成开发环境、C#语言的基础知识、面向对象的程序...
  • IOS网络编程与云端应用最佳实践,完整扫描版

    千次下载 热门讨论 2014-10-11 21:57:18
    《清华开发者书库:iOS网络编程与云端应用最佳实践》是介绍iOS 6网络编程和云端应用开发技术书籍,介绍了苹果网络、数据交换格式、Web Service、iCloud、定位服务、地图、推送通知、Newsstand、应用内购买、Passbook...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 599,800
精华内容 239,920
关键字:

网络编程技术