一、什么是socket?


socket顾名思义就是套接字的意思,用于描述地址和端口,是一个通信链的句柄。应用程序通过socket向网络发出请求或者回应。

socket编程有三种,流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM),原始套接字(SOCK_RAW),前两者较常用。基于TCP的socket编程是流式套接字。


二、TCP/IP协议


要理解socket必须的得理解tcp/ip,它们之间好比送信的线路和驿站的作用,比如要建议送信驿站,必须得了解送信的各个细节。

TCP/IP协议不同于iso的7个分层,它是根据这7个分层,将其重新划分,好比打扫卫生,本来有扫帚,垃圾斗,抹布,涂料,盆栽等就好比OSI的标准几个分层,tcp/ip根据用途和功能,将扫帚,垃圾斗放到粗略整理层,抹布涂料放到中度整理层,盆栽放到最终效果层。这里TCP/IP也对OSI的网络模型层进行了划分:大致如下:

TCP/IP协议参考模型把所有的TCP/IP系列协议归类到四个抽象层中

应用层:TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 等等

传输层:TCP,UDP

网络层:IP,ICMP,OSPF,EIGRP,IGMP

数据链路层:SLIP,CSLIP,PPP,MTU

每一抽象层建立在低一层提供的服务上,并且为高一层提供服务,看起来大概是这样子的

通过上面的图形,由于底一层的需要向高一层的提供服务,我们大致的理解应用程序需要传输层的tcp和网络层的ip协议提供服务,但是我们这章要分析的socket它是在tcpip协议的那一部分呢,就好比,我们的通讯线路已经有明确的规定,我们的驿站要设计在哪个地方一样


三、回过头再来理解socket


到目前为止,大致的了解了应用程序和tcpip协议的大致关系,我们只是知道socket编程是在tcp/IP上的网络编程,但是socket在上述的模型的什么位置呢。这个位置被一个天才的理论家或者是抽象的计算机大神提出并且安排出来

我们可以发现socket就在应用程序的传输层和应用层之间,设计了一个socket抽象层,传输层的底一层的服务提供给socket抽象层,socket抽象层再提供给应用层,问题又来了,应用层和socket抽象层之间和传输层,网络层之间如何通讯的呢,了解这个之前,我们还是回到原点

要想理解socket编程怎么通过socket关键词实现服务器和客户端通讯,必须得实现的了解tcp/ip是怎么通讯的,在这个的基础上在去理解socket的握手通讯

在tcp/ip协议中,tcp通过三次握手建立起一个tcp的链接,大致如下

第一次握手:客户端尝试连接服务器,向服务器发送syn包,syn=j,客户端进入SYN_SEND状态等待服务器确认

第二次握手:服务器接收客户端syn包并确认(ack=j+1),同时向客户端发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手

根据tcp的三次握手,socket也定义了三次握手,也许是参考tcp的三次握手,一些计算机大神们画出了socket的三次握手的模型图

在上面图的基础上,如果我们得到上面的图形,需要我们自己开发一些接口,来满足上面的通讯的三次握手,问题就出来了,我们会需要开发哪些函数


四、socket的一些接口函数原理


通过上面的图,我们清楚,我们好比一些泛型的程序员,一些理论提供者提供给了我们上面的图形的理论,我们需要做的就是讲上面的图形的抽象化的东西具体化

第一次握手:客户端需要发送一个syn j 包,试着去链接服务器端,于是客户端我们需要提供一个链接函数

第二次握手:服务器端需要接收客户端发送过来的syn J+1 包,然后在发送ack包,所以我们需要有服务器端接受处理函数

第三次握手:客户端的处理函数和服务器端的处理函数

三次握手只是一个数据传输的过程,但是,我们传输前需要一些准备工作,比如将创建一个套接字,收集一些计算机的资源,将一些资源绑定套接字里面,以及接受和发送数据的函数等等,这些功能接口在一起构成了socket的编程

 下面大致的按照客户端和服务端将所需的函数详细的列举出来



六、编程步骤


1、server端

#include<iostream>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;/*初始化套接字库*/
void initialization() {WORD w_req = MAKEWORD(2,2);//版本号WSADATA wsadata;int err;err = WSAStartup(w_req,&wsadata);if (err != 0) {cout << "初始化套接字库失败!" << endl;}else {cout << "初始化套接字库成功!" << endl;}//检测版本号if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {cout << "套接字库版本号不符!" << endl;}else {cout << "套接字库版本正确!" << endl;}
}int main() {//定义长度变量int send_len = 0;int recv_len = 0;int len = 0;//定义发送缓冲区和接受缓冲区char send_buf[100];char recv_buf[100];//定义服务端套接字,接受请求套接字SOCKET s_server;SOCKET s_accept;//服务端地址客户端地址SOCKADDR_IN server_addr;SOCKADDR_IN accept_addr;initialization();//填充服务端信息server_addr.sin_family = AF_INET;server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);server_addr.sin_port = htons(12341);//创建套接字s_server = socket(AF_INET,SOCK_STREAM,0);if (bind(s_server, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {cout << "套接字绑定失败!" << endl;WSACleanup();}else {cout << "套接字绑定成功!" << endl;}//设置套接字为监听状态if (listen(s_server, SOMAXCONN) < 0) {cout << "设置监听失败!" << endl;WSACleanup();}else {cout << "设置监听成功!" << endl;}cout << "服务端正在监听连接,请稍等---" << endl;//接受连接请求len = sizeof(SOCKADDR);s_accept = accept(s_server, (SOCKADDR*)&accept_addr, &len);if (s_accept == SOCKET_ERROR) {cout << "连接失败!" << endl;WSACleanup();return 0;}cout << "连接建立,准备接受数据" << endl;//接受数据while (1) {recv_len = recv(s_accept,recv_buf,100,0);if (recv_len < 0) {cout << "接受失败!" << endl;break;}else {cout << "客户端信息:" << recv_buf << endl;}cout << "请输入回复信息:";cin >> send_buf;send_len = send(s_accept,send_buf,100,0);if (send_len < 0) {cout << "发送失败!" << endl;break;}}return 0;
}

2、client端

#include<iostream>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;void initialization() {//初始化套接字库WORD w_req = MAKEWORD(2,2);//版本号WSADATA wsadata;int err;err = WSAStartup(w_req,&wsadata);if (err != 0) {cout << "初始化套接字库失败!" << endl;}else {cout << "初始化套接字库成功!" << endl;}//检测版本号if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {cout << "套接字库版本号不符!" << endl;WSACleanup();}else {cout << "套接字符版本号正确!" << endl;}
}
int main() {//定义长度变量int send_len = 0;int recv_len = 0;//定义发送缓冲区和接受缓冲区char send_buf[100];char recv_buf[100];//定义服务端套接字,接受请求套接字SOCKET s_server;//服务端地址客户端地址SOCKADDR_IN server_addr;initialization();//填充服务端信息server_addr.sin_family = AF_INET;server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");server_addr.sin_port = htons(12341);//创建套接字s_server = socket(AF_INET, SOCK_STREAM, 0);if (connect(s_server, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {cout << "服务器连接失败!" << endl;WSACleanup();}else {cout << "服务器连接成功!" << endl;}//发送数据while (1) {cout << "请输入发送信息:" << endl;cin >> send_buf;send_len = send(s_server, send_buf, 100, 0);if (send_len < 0) {cout << "发送失败!" << endl;break;}recv_len = recv(s_server,recv_buf,100,0);if (recv_len < 0) {cout << "接受失败!" << endl;break;}else {cout << "服务端信息:" << recv_buf << endl;}}//关闭套接字closesocket(s_server);//释放DLL资源WSACleanup();return 0;
}

Socket编程(简单(C++)实现TCP通信)相关推荐

  1. 基于MFC的socket编程(异步非阻塞通信)

    对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手.许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等,初学者往往迷惑不清,只知其 ...

  2. Linux的SOCKET编程 简单演示

    转载:http://blog.csdn.net/hguisu/article/details/7445768/ Linux的SOCKET编程详解 1. 网络中进程之间如何通信 进 程通信的概念最初来源 ...

  3. socket编程简单Demo讲解及源码分享(C# Winform 内网)

    首先是什么是socket编程? 推荐大家看百度百科的解释:https://baike.baidu.com/item/socket/281150?fr=aladdin 百科对于定义讲的很详细,就不再叙述 ...

  4. 网络编程1-cs模型的TCP通信

    前话 协议:是数据传输和数据的解释的规则 数据在网络中传递需要进行封装.数据在四层模型中进入网络环境的传递过程(解封装时是逆的过程,最终露出数据)是: 数据->应用层协议->传输层协议-& ...

  5. Java——网络编程(UDP与TCP通信及实现聊天案例)

    目录 1.什么是网络通信协议? 2.TCP/IP协议 3.协议分类 3.1.UDP协议 3.2.TCP协议 4.网络编程三大要素 4.1.协议 4.2.IP地址 4.3.端口号 5.InetAddre ...

  6. 网络基础:套接字编程,UDP和TCP通信程序

    文章目录 字节序 套接字编程 客户端与服务端 ★ netstat命令 ★ UDP通信程序 通信流程: 接口: 流程外的重要接口: 服务端代码 客户端代码 TCP通信程序 通信流程: 接口: 代码实例: ...

  7. c# WINFORM SOCKET编程-简单聊天程序(服务端)

    初学C#的SOCKET编程,照着网上的代码写下来,程序总是有问题,经过自己长时间的调试,完成程序,以下是原码,有需要可以参考一下,还不完善,欢迎大家批评指正.(这里的代码没更新,附件重新上传更新,在另 ...

  8. 学习笔记(05):Python网络编程并发编程-基于socket实现简单套接字通信

    立即学习:https://edu.csdn.net/course/play/24458/296234?utm_source=blogtoedu 1.服务器端 #以打电话通讯为例子进行说明 #导入相应的 ...

  9. Socket编程简单示例

    传统Socket基于BIO实现一个简单的聊天服务器 服务端代码如下 publicclassMyServerSocket {publicstaticvoidmain(String[] args)thro ...

  10. Socket编程(4)TCP粘包问题及解决方案

    ① TCP是个流协议,它存在粘包问题 TCP是一个基于字节流的传输服务,"流"意味着TCP所传输的数据是没有边界的.这不同于UDP提供基于消息的传输服务,其传输的数据是有边界的.T ...

最新文章

  1. java内部类人打电话依赖手机_Java内部类及反射类面试问题,90%的人都不知道
  2. 用数据分析《你好,李焕英》“斐妈”爆红的真相
  3. (0016)iOS 开发之Mac上Navicat Premium 创建远程连接和本地连接
  4. python socket代码_python入门之socket代码练习
  5. 了解播放过滤器API
  6. LeetCode MySQL 1440. 计算布尔表达式的值(case when then else end)
  7. ios 分段 判断 小说阅读器_还在用别的小说阅读器?今天教你用Python制作简易小说阅读器!...
  8. CodeGym—Java自学神器
  9. 写代码常用英文及缩写
  10. 1600k 打印头测试软件,巧修 LQ-1600K打印头.doc
  11. 《赛灵思中国通讯》学习记录第1期:为何使用Zynq SoC可以让企业产品利润激增
  12. 页面置换算法详解(10种)
  13. JDK8环境配置教程
  14. 【ArcGIS小技巧视频教程】(5):在ArcGIS中挂接其他数据
  15. 计算机网络(谢希仁第七版)期末重点
  16. 贝叶斯公式求解公园凉鞋问题
  17. 易飞8无销售报价的BOM成本参考
  18. fir.im Weekly - 如何打造 Github 「爆款」开源项目
  19. SHR之员工合同解除
  20. HDR视频色调映射算法(之四:Display adaptive TMO)

热门文章

  1. DFS算法(含步骤总结)
  2. POST请求的两种格式
  3. python对数组进行排序_python 字典、数组排序
  4. 【PLC学习二】OB块
  5. SQL 求TOP N(多种解法)
  6. [PPT 设置自动换片时间] PPT有几张老自动跳过,问题的解决过程记录
  7. 益聚星荣:欧莱雅遭近2000消费者集体投诉…
  8. 3天涨2000粉丝,总结了9个小技巧,拍视频如何快速涨粉?
  9. 气质结果重复性比较和pdf结果文件的批处理
  10. python TCP 通信