《网络安全编程基础》之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. HDU 2824 The Euler function --------欧拉模板

    The Euler function Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  2. HTML5实现输入密码(六个格子)

    我的思路:用六个li充当六个格子,同时将input框隐藏,点击承载六个格子的容器时,使焦点聚焦在input上,可以输入.通过监听input框输入的长度,控制格子内小黑点是否显示,同时用正则替换非数字. ...

  3. centos 删除文件和目录

    每次都记不住,发个文章记录一下.直接rm就可以了,不过要加两个参数-rf 即:rm -rf 目录名字-r 就是向下递归,不管有多少级目录,一并删除-f 就是直接强行删除,不作任何提示的意思 删除文件夹 ...

  4. 【代码笔记】iOS-cell折叠

    一,效果图. 二,工程图. 三,代码. AppDelegate.h #import <UIKit/UIKit.h> //加入头文件 #import "myQQView.h&quo ...

  5. Android上实现视频录制

    首先,我们肯定要用到摄像头,因此需要在Manifest文件中声明使用权限: <uses-permission android:name="android.permission.CAME ...

  6. 如何drop大表的中不用的字段 set unused column

    转自 http://foxmile.blog.163.com/blog/static/81169805201143191957184/ 我 们要删除表中不用的字段,如果直接drop column,对于 ...

  7. 转 Js窗体window大小设置

    网页可见区域宽:document.body.clientWidth  网页可见区域高:document.body.clientHeight  网页可见区域宽:document.body.offsetW ...

  8. LeetCode题解之Find the Difference

    1.题目描述 2.题目分析 比较两个字符串中加入的一个字符,由于可能在字符串中加入一个已经存在的字符,因此使用hash table 去统计字符个数最好. 3.代码 char findTheDiffer ...

  9. 4.Spring——xml配置文件

    如果使用Maven构建项目,spring在加载xsd文件时总是先试图在本地查找xsd文件(spring的jar包中已经包含了所有版本的xsd文件), 如果没有找到,才会转向去URL指定的路径下载.ap ...

  10. Orcal数据库,使用EF的自增处理

    1.定义EF拦截器,截获执行命令前的操作.修改执行sql.还需要定义orcal序列,供自增使用 using System; using System.Collections.Generic; usin ...