《网络安全编程基础》之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是因为字符串以'\0'结尾
char recvBuf[50];
recv(socksend,recvBuf,50,0); //recv()
printf("%s\n",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\n",recvBuf);
send(socketClient,"你好,我是客户端",strlen("你好,我是客户端")+1,0); //send()
closesocket(socketClient); WSACleanup();
}

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

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

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

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

解决办法:

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



解决办法:

  1. 右击Visual C++ 6.0快捷方式,选择"属性",在"目标(T):"中查看其可执行文件的地址为:"C:\Program Files (x86)\Microsoft Visual Studio\Common\MSDev98\Bin\MSDEV.EXE",找到MSDEV.EXE;
  2. 右键选择"属性",在"常规"选项卡下将MSDEV.EXE更名为MSDEV1.EXE:

  3. 在"兼容性"选项卡下勾选"以兼容模式运行这个程序",将兼容模式选择Windows XP(Service Pack2)",并将权限等级勾选为“以管理员身份运行此程序”,点击确定:

  4. 重新运行Visual C++ 6.0,奈斯,已经成功了!

  5. 老规矩,新建一个Win32控制台工程,并以Hello World方式打开:



  6. 尽情开始你的表演吧~

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

问题详细解释:

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

解决办法:

  1. 右键单击项目工程中的cpp文件,在菜单Project-->Settings-->C/C++-->Precompile Header,设置为第一项:Not using precompile headers。

  2. 在.cpp文件开头添加包含文件stdafx.h:#include "stdafx.h"
  3. 重新编译即可~

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

解决办法:

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

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

解决办法:

自己疏忽原因,在前面加上char sendBuf[50]即可~

至此,编译终于成功通过orz...



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

点击运行,弹出Windows防火墙……



点击"允许访问"后,额……







??☺???

解决办法:

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

问题根源:

在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是因为字符串以'\0'结尾
a=recv(socksend,recvBuf,50,0); //recv()
printf(" Client:%s\n",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\n",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)

《网络安全编程基础》之Socket编程的更多相关文章

  1. 第1章 网络编程基础(2)——Socket编程原理

    Socket编程原理 Socket是网络通信端点的一种抽象,它提供了一种发送和接收数据的机制. 流socket(SOCK_STREAM):双向.有序.无重复.并且无记录边界 数据报Socket(SOC ...

  2. Python 基础之socket编程(二)

    Python 基础之socket编程(二) 昨天只是对socket编程做了简单的介绍,只是把socket通信的框架搭建起来,要对其中的功能进行进一步的扩充,就来看看今天的料哈! 一.基于tcp的套接字 ...

  3. python基础之socket编程 (转自林海峰老师)

    python基础之socket编程   阅读目录 一 客户端/服务器架构 二 osi七层 三 socket层 四 socket是什么 五 套接字发展史及分类 六 套接字工作流程 七 基于TCP的套接字 ...

  4. Python 基础之socket编程(三)

    python 基础之socket编程(三) 前面实现的基于socket通信只能实现什么呢?在tcp协议的通信中就是一个用户说一句,服务端给你回一句,你再给服务端说一句,服务端再给你回一句,就这样一直友 ...

  5. Python 基础之socket编程(一)

    Python 基础之socket编程(一) 可以进行通信玩儿了,感觉不错不错,网络通信就像打电话,我说一句你听一句之后,你再说一句,我听一句,就这样.....下去了.不扯淡了,来来来,看看今天都搞了点 ...

  6. 从零开始学Python第八周:网络编程基础(socket)

    Socket网络编程 一,Socket编程 (1)Socket方法介绍 Socket是网络编程的一个抽象概念.通常我们用一个Socket表示"打开了一个网络链接",而打开一个Soc ...

  7. 网络编程基础之TCP编程学习(一)

    网络编程基础了解 socket套接字 socket是一种通讯机制,它包含一整套的调用接口和数据结构的定义,他给应用程序提供了使用如TCP/UDP等网络通讯的手段. linux中的网络编程通过socke ...

  8. Spark编程基础_RDD初级编程

    摘要:Spark编程基础_RDD初级编程 RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素 ...

  9. 十三python基础之socket编程

      阅读目录 一 客户端/服务器架构 二 osi七层 三 socket层 四 socket是什么 五 套接字发展史及分类 六 套接字工作流程 七 基于TCP的套接字 八 基于UDP的套接字 九 粘包现 ...

  10. python基础之socket编程

    一 客户端/服务器架构 二 osi七层 三 socket层 四 socket是什么 五 套接字发展史及分类 六 套接字工作流程 七 基于TCP的套接字 八 基于UDP的套接字 九 粘包现象 十 什么是 ...

随机推荐

  1. Hive 编程指南—笔记

    1. 基础 1.1 Hive 解决问题的背景? 用户如何从一个现有的数据基础架构转移到 Hadoop 上,而这个基础架构是基于传统的关系数据库和 SQL 的? Hive 提供了一个被称为 HQL 的 ...

  2. MS SQL Server数据库在线管理工具

    MS SQL Server数据库以其优异的性能,被广泛使用,特别是政务,医疗行业.但是远程维护挺不方便的,目前有一款基于WEB的工具TreeSoft数据库管理系统. 免安装,直接解压就可以用了.直接通 ...

  3. 使用Hexo和Github Pages快速搭建个人博客

    在编程路上,每天都在网上查看别人的博客,大牛的文章写得通俗易懂,同时博客网站也非常华丽.作为出入编程的一枚小白也想拥有这样一个自己的网站.那就立马去买一个域名了,在网上找教程来搭建. 搭建的过程还算比 ...

  4. 修改input被选中的默认样式

    input:focus{    outline: none;     border: 1px solid #fff; } 或者 input[type=text]:focus{   outline: n ...

  5. drupal7 查看哪些模块实现了某个钩子

    module_implements($hook) 可参考函数module_invoke_all function module_invoke_all($hook) { $args = func_get ...

  6. 使用 Leaflet 显示 ArcGIS 生成西安80坐标的地图缓存

    Leaflet 是一个非常小巧灵活的 Geo js 库,esri 本身也在 Github 上有 leaflet 的相关项目.但是 leaflet 本身支持 Web Mercator Auxiliary ...

  7. Data Encryption Errors After Restoring Microsoft Dynamics CRM Database

    If you’re seeing an error similar to the one above, you’ve probably done a database backup and resto ...

  8. css动画和jq动画的简单区分

    有很多不怎么用css3写动画的同学经常会对其中css3的transform,transition,translate,animation,@keyframes等等动画属性混淆错乱,经常使用了发现没有效 ...

  9. Android 后台线程,timertask实现定期更新时间

    简述:这是一类定时功能的原型,用来在后台线程中运行一些定时的服务,比如定时修改时间 知识点: 1. Android多线程的消息通信(handler) 2. Java中时间的获取,以及String的格式 ...

  10. JS BOM对象 History对象 Location对象

    一.BOM对象 BOM(浏览器对象模型),可以对浏览器窗口进行访问和操作 window对象 所有浏览器都支持 window 对象. 概念上讲.一个html文档对应一个window对象. 功能上讲: 控 ...