• 《网络安全编程基础》之Socket编程


    《网络安全编程基础》之Socket编程

    我的代码

    server.c

    // server.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <Winsock2.h>
    #pragma comment(lib,"ws2_32.lib") //添加静态链接库文件
    void main(int argc,char* argv[])
    {
        WSADATA wsadata;
        WSAStartup(MAKEWORD(1,1),&wsadata);
    
        SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0); //socket()
        /***地址结构体***/
        SOCKADDR_IN addrSvr;
        addrSvr.sin_family=AF_INET;
        addrSvr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
        addrSvr.sin_port=htons(6000);
        /**************/
        bind(sockSrv,(SOCKADDR*)&addrSvr, sizeof(SOCKADDR)); //bind()
        listen(sockSrv,5); //listen()
        SOCKADDR_IN addrClient;
        int len= sizeof(SOCKADDR);
        while(1) //加循环是为了应对多个客户端连接此服务器的情况
        {
        	SOCKET socksend=accept(sockSrv,(SOCKADDR*)&addrClient,&len); //accept()
    		char sendBuf[50]; //
        	sprintf(sendBuf,"你好,我是服务器"); //使用sprintf给字符串赋值、连接字符串比较方便
        	send(socksend,sendBuf,strlen(sendBuf)+1,0); //send(),+1是因为字符串以''结尾
        	char recvBuf[50];
        	recv(socksend,recvBuf,50,0); //recv()
        	printf("%s
    ",recvBuf);
        	closesocket(socksend);
        }
        /*closesocket(sockSrv);
        WSACleanup();*/ //while(1)后的死代码
    }
    

    client.c

    // Client.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <Winsock2.h>
    #pragma comment(lib,"ws2_32.lib") //添加静态链接库文件
    void main(int argc,char* argv[])
    {
        WSADATA wsadata;
        WSAStartup(MAKEWORD(1,1),&wsadata);
    
        SOCKET socketClient=socket(AF_INET,SOCK_STREAM,0); //socket()
        /***地址结构体***/
        SOCKADDR_IN addrSvr;
        addrSvr.sin_family=AF_INET;
        addrSvr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
        addrSvr.sin_port=htons(6000);
        /**************/
        connect(socketClient,(SOCKADDR*)&addrSvr,sizeof(SOCKADDR)); //connect()
    	char recvBuf[50];
    	recv(socketClient,recvBuf,50,0); //recv()
    	printf("%s
    ",recvBuf);
    	send(socketClient,"你好,我是客户端",strlen("你好,我是客户端")+1,0);  //send()
    	closesocket(socketClient);
    
        WSACleanup();
    }
    

    代码调试过程中出现的问题

    问题一:macOS High Sierra下Clion出现CMake Error

    toDJA.jpg

    解决办法:百度无果,重新打开Clion发现连license都过期了,多半是没救了,只能老老实实用命令行试试了>_<

    toBid.png

    问题二:终端下编译server.c提示找不到"winsock2.h"头文件

    torRI.png

    解决办法:

    Mac下编程用什么替换windows.h头文件?

    • 我在mac下编程,想使用清屏指令cls不好使,也不能用windows.h头文件。请大家帮我想想怎么办。还有在mac下能用system" "么?

    • 不行,你不能在除了 Windows 的任何系统上使用 Windows.h。你要理解 API 的概念,windows.h 这个头文件是 Windows 带的,而不是 C 语言自身有的。事实上,出了 Windows,没有任何系统——实际上也是在真真切切用 C 的系统——例如所有在跑类 Unix,比如 OS X、Linux 甚至 FreeBSD 上的,都不能用 Windows 这套 API。这也是为什么坊间都说 OS X 是适合做编程,特别是适合学编程的,因为 OS X 是“体制内”,也就使用和全世界除了 Windows 之外所有的东西都互通的底层架构的,而且它在过去的大部分时候都要比各类 Linux 要容易上手,所谓的“更优雅”。

    • ……

    在百度知道上看到了这段对话后感觉已经凉了,还好我有windows8.1虚拟机,这回再也不怕找不到windows头文件了吧!

    问题三:windows8.1虚拟机不兼容VC6.0

    towIH.png
    toszt.png

    解决办法:

    1. 右击Visual C++ 6.0快捷方式,选择"属性",在"目标(T):"中查看其可执行文件的地址为:"C:Program Files (x86)Microsoft Visual StudioCommonMSDev98BinMSDEV.EXE",找到MSDEV.EXE;
    2. 右键选择"属性",在"常规"选项卡下将MSDEV.EXE更名为MSDEV1.EXE:
      to6QP.png
    3. 在"兼容性"选项卡下勾选"以兼容模式运行这个程序",将兼容模式选择Windows XP(Service Pack2)",并将权限等级勾选为“以管理员身份运行此程序”,点击确定
      tocsf.png
    4. 重新运行Visual C++ 6.0,奈斯,已经成功了!
      togL8.png
    5. 老规矩,新建一个Win32控制台工程,并以Hello World方式打开:
      toReS.png
      toWdg.png
    6. 尽情开始你的表演吧~

    问题四:编译error1——在编译VC时候,出现fatal error C1010: unexpected end of file while looking for precompiled head

    tofoQ.png

    问题详细解释:

    致命错误C1010,在寻找预编译指示头文件时,文件未预期结束。就是没有找到预编译指示信息的问文件。顾名思义就是预编译因为缺少了预编译文件而失败。解决方法显然可以取消预编译,或者帮助编译器找到预编译文件。

    解决办法:

    1. 右键单击项目工程中的cpp文件,在菜单Project-->Settings-->C/C++-->Precompile Header,设置为第一项:Not using precompile headers。
      to4ij.png
    2. 在.cpp文件开头添加包含文件stdafx.h:#include "stdafx.h"
    3. 重新编译即可~

    问题五:编译error2——地址结构体大小写表示问题

    to5Js.png

    解决办法:

    不知道是不是编译环境不同的原因,学校电脑上的地址结构体成员addrSvr.sin_Family到我win8.1虚拟机上就必须改成addrSvr.sin_family了,满脸黑线= =
    toIWn.png

    问题六:编译error3——sendBuf未定义

    toozq.png

    解决办法:

    自己疏忽原因,在前面加上char sendBuf[50]即可~
    至此,编译终于成功通过orz...
    to7Q0.png
    tTZYd.png

    问题七:烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫

    点击运行,弹出Windows防火墙……
    toHyV.png
    点击"允许访问"后,额……
    toLeU.png
    tTa60.png
    tTb9A.png
    ??☺???

    解决办法:

    百度一下,发现又打开了一个新世界的大门:

    问题根源:

    在windows平台下,ms的编译器(也就是vc带的那个)在 Debug 模式下,会把未初始化的栈内存全部填成 0xcc,用字符串来看就是”烫烫烫烫烫烫烫”,未初始化的堆内存全部填成0xcd,字符串看就是“屯屯屯屯屯屯屯屯”。

    说人话:定义的字符串没有初始化就会出现这样的情况

    解决办法:初始化一下

    1. char p[] = “0”;
    2. ZeroMemory
    3. memset

    那么这里是由于先运行client.c再运行server.c导致

    	char recvBuf[50];
    	recv(socksend,recvBuf,50,0); //recv()
    ```中数组`recvBuf`未被初始化的原因,解决方法当然是**先运行server.c再运行client.c**咯,这样客户端就能receive到服务器发来的recvBuf啦~
    
    ##运行结果
    
    - 一个客户端连接一个服务器:
    	![tobLT.png](https://s1.ax1x.com/2017/10/20/tobLT.png)
    - 多个客户端同时连接一个服务器:
    	![toOwF.png](https://s1.ax1x.com/2017/10/20/toOwF.png)
    	
    ##高级版mySocket——实现服务器客户端互发消息尬聊>_<
    ###核心伪代码
    - server.c:
    
    	```
    	do{
    		gets(sendBuf);
    		send();
    		recv();
    		puts(recvBuf);
    	}while(返回值不为-1);
    	```
    - client.c:
    
    	```
    	do{
    		recv();
    		puts(recvBuf);
    		gets(sendBuf);
    		send();
    	}while(返回值不为-1);
    	```
    	
    ###完整代码
    
    - server.c:
    
    	```
    	// server.cpp : Defines the entry point for the console application.
    	//
    
    	#include "stdafx.h"
    	#include <Winsock2.h>
    	#include <string.h>
    	#pragma comment(lib,"ws2_32.lib") //添加静态链接库文件
    	void main(int argc,char* argv[])
    	{
        	WSADATA wsadata;
        	WSAStartup(MAKEWORD(1,1),&wsadata);
    	
        	SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0); //socket()
        	/***地址结构体***/
        	SOCKADDR_IN addrSvr;
        	addrSvr.sin_family=AF_INET;
    	    addrSvr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
        	addrSvr.sin_port=htons(6000);
        	/**************/
        	bind(sockSrv,(SOCKADDR*)&addrSvr, sizeof(SOCKADDR)); //bind()
        	listen(sockSrv,5); //listen()
        	SOCKADDR_IN addrClient;
        	int len= sizeof(SOCKADDR);
        	while(1)
        	{
        		SOCKET socksend=accept(sockSrv,(SOCKADDR*)&addrClient,&len); //accept()
     			char sendBuf[50]; 
    			char recvBuf[50];
     			int a;
     			do{
        			printf("Me:");
     				gets(sendBuf);
     				fflush(stdin);
        			send(socksend,sendBuf,strlen(sendBuf)+1,0); //send(),+1是因为字符串以''结尾
        			a=recv(socksend,recvBuf,50,0); //recv()
        			printf("  Client:%s
    ",recvBuf);
     			}while(a!=-1);
     
        		closesocket(socksend);
        	}
        		closesocket(sockSrv);
        		WSACleanup();
    	}
    	```
    
    - client.c:
    
    	```
    	// Client.cpp : Defines the entry point for the console application.
    	//
    	
    	#include "stdafx.h"
    	#include <Winsock2.h>
    	#pragma comment(lib,"ws2_32.lib") //添加静态链接库文件
    	void main(int argc,char* argv[])
    	{
        	WSADATA wsadata;
        	WSAStartup(MAKEWORD(1,1),&wsadata);
    
        	SOCKET socketClient=socket(AF_INET,SOCK_STREAM,0); //	socket()
        	/***地址结构体***/
        	SOCKADDR_IN addrSvr;
        	addrSvr.sin_family=AF_INET;
        	addrSvr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
        	addrSvr.sin_port=htons(6000);
        	/**************/
        	connect(socketClient,(SOCKADDR*)&addrSvr,sizeof(SOCKADDR));
    		char recvBuf[50];
    		char sendBuf[50];
    		int a;
    		do{
    			a=recv(socketClient,recvBuf,50,0);
    			printf("		Server:%s
    ",recvBuf);
    			printf("Me:");
    			gets(sendBuf);
    			fflush(stdin);
    			send(socketClient,sendBuf,strlen(sendBuf)+1,0);
    		}while(a!=1);
    
    		closesocket(socketClient);
    
        	WSACleanup();
    	}
    	
    	```
    
    
    ###运行结果(这不是尬聊是什么hhh)
    ![UKuNV.png](https://s1.ax1x.com/2017/10/25/UKuNV.png)
    
    ##参考资料
    - [Mac&iOS Socket编程](http://m.blog.csdn.net/bravegogo/article/details/50938454)
    - [Mac下编程用什么替换windows.h头文件](https://zhidao.baidu.com/question/369558222732704524.html?fr=ala&word=mac下windows头文件)
    - [如何在win8.1下运行VC6.0](https://jingyan.baidu.com/article/2009576198453dcb0721b4a1.html)
    - [关于SOCKET编程中“烫烫烫...”的问题](http://m.blog.csdn.net/zhichitianya1234/article/details/76291374)
    - [文件写入或控制台输出显示:"烫烫烫烫"问题解决办法](http://m.blog.csdn.net/alex__0805/article/details/47381531)
  • 相关阅读:
    达叔系列——神经网络编程基础
    win10安装pytorch——前面有坑,快跳进去鸭
    Python基础(六)——面向对象编程
    Python基础(五)——闭包与lambda的结合
    Python基础(四)——迭代器/对象,生成器
    Mysql优化(出自官方文档)
    Mysql优化(出自官方文档)
    Scala语言笔记
    Scala语言笔记
    Scala语言笔记
  • 原文地址:https://www.cnblogs.com/crazymosquito/p/7698871.html
Copyright © 2020-2023  润新知