对TCP/IP、UDP、Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵。那么我想问:

  1.     什么是TCP/IP、UDP?
  2.     Socket在哪里呢?
  3.     Socket是什么呢?
  4.     你会使用它们吗?

什么是TCP/IP、UDP?

     TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种。这里有一张图,表明了这些协议的关系。


图1

   TCP/IP协议族包括运输层、网络层、链路层。现在你知道TCP/IP与UDP的关系了吧。

Socket在哪里呢?

   在图1中,我们没有看到Socket的影子,那么它到底在哪里呢?还是用图来说话,一目了然。


图2

   原来Socket在这里。

Socket是什么呢?

   Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

你会使用它们吗?
前人已经给我们做了好多的事了,网络间的通信也就简单了许多,但毕竟还是有挺多工作要做的。以前听到Socket编程,觉得它是比较高深的编程知识,但是只要弄清Socket编程的工作原理,神秘的面纱也就揭开了。
一个生活中的场景。你要打电话给一个朋友,先拨号,朋友听到电话铃声后提起电话,这时你和你的朋友就建立起了连接,就可以讲话了。等交流结束,挂断电话结束此次交谈。 生活中的场景就解释了这工作原理,也许TCP/IP协议族就是诞生于生活中,这也不一定。


图3

   先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。在这里我就举个简单的例子,我们走的是TCP协议这条路(见图2)。例子用MFC编写,运行的界面如下:


图4


图5

   在客户端输入服务器端的IP地址和发送的数据,然后按发送按钮,服务器端接收到数据,然后回应客户端。客户端读取回应的数据,显示在界面上。下面是接收数据和发送数据的函数:
int    Receive(SOCKET fd,char *szText,int len){int cnt;int rc;cnt=len;while(cnt>0){rc=recv(fd,szText,cnt,0);if(rc==SOCKET_ERROR){return -1;}if(rc==0)return len-cnt;szText+=rc;cnt-=rc;}return len;}int Send(SOCKET fd,char *szText,int len)
{int cnt;int rc;cnt=len;while(cnt>0){rc=send(fd,szText,cnt,0);if(rc==SOCKET_ERROR){return -1;}if(rc==0)return len-cnt;szText+=rc;cnt-=rc;}return len;}

服务器端:

   在服务器端,主要是启动Socket和监听线程。
#define DEFAULT_PORT      2000void CServerDlg::OnStart(){sockaddr_in local;DWORD dwThreadID = 0;local.sin_family=AF_INET;//设置的端口为DEFAULT_PORT。local.sin_port=htons(DEFAULT_PORT);//IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址。local.sin_addr.S_un.S_addr=INADDR_ANY;//初始化Socketm_Listening = socket(AF_INET,SOCK_STREAM,0);if(m_Listening == INVALID_SOCKET){return ;}//将本地地址绑定到所创建的套接字上if(bind(m_Listening,(LPSOCKADDR)&local,sizeof(local)) == SOCKET_ERROR ){closesocket(m_Listening);return ;}//创建监听线程,这样也能响应界面上操作。m_hListenThread = ::CreateThread(NULL,0,ListenThread,this,0,&dwThreadID);m_StartBtn.EnableWindow(FALSE);m_StopBtn.EnableWindow(TRUE);}

监听线程函数:

DWORD WINAPI CServerDlg::ListenThread(LPVOID lpparam)
{CServerDlg* pDlg = (CServerDlg*)lpparam;if(pDlg == NULL)return 0;SOCKET  Listening = pDlg->m_Listening;//开始监听是否有客户端连接。if(listen(Listening,40) == SOCKET_ERROR){return 0;}char szBuf[MAX_PATH];//初始化memset(szBuf,0,MAX_PATH);while(1){SOCKET ConnectSocket;sockaddr_in    ClientAddr;int                  nLen = sizeof(sockaddr);//阻塞直到有客户端连接,不然多浪费CPU资源。ConnectSocket = accept(Listening,(sockaddr*)&ClientAddr,&nLen);//都到客户端的IP地址。char *pAddrname = inet_ntoa(ClientAddr.sin_addr);pDlg->Receive(ConnectSocket,szBuf,100);//界面上显示请求数据。pDlg->SetRequestText(szBuf);strcat(szBuf," :我是老猫,收到(");strcat(szBuf,pAddrname);strcat(szBuf,")");//向客户端发送回应数据pDlg->Send(ConnectSocket,szBuf,100);}return 0;}
   服务器端一直在监听是否有客户端连接,如有连接,处理客户端的请求,给出回应,然后继续监听。

客户端:

   客户端的发送函数:
#define DEFAULT_PORT      2000void CClientDlg::OnSend(){DWORD dwIP = 0;      TCHAR szText[MAX_PATH];memset(szText,0,MAX_PATH);m_IP.GetWindowText(szText,MAX_PATH);//把字符串形式的IP地址转成IN_ADDR结构需要的形式。dwIP = inet_addr(szText);m_RequestEdit.GetWindowText(szText,MAX_PATH);sockaddr_in local;SOCKET socketTmp;//必须是AF_INET,表示该socket在Internet域中进行通信local.sin_family=AF_INET;//端口号local.sin_port=htons(DEFAULT_PORT);//服务器的IP地址。local.sin_addr.S_un.S_addr=dwIP;初始化SocketsocketTmp=socket(AF_INET,SOCK_STREAM,0);//连接服务器if(connect(socketTmp,(LPSOCKADDR)&local,sizeof(local)) < 0){closesocket(socketTmp);MessageBox("连接服务器失败。");return ;}//发送请求,为简单只发100字节,在服务器端也规定100字节。Send(socketTmp,szText,100);//读取服务器端返回的数据。memset(szText,0,MAX_PATH);//接收服务器端的回应。Receive(socketTmp,szText,100);TCHAR szMessage[MAX_PATH];memset(szMessage,0,MAX_PATH);strcat(szMessage,szText);//界面上显示回应数据。m_ReplyBtn.SetWindowText(szMessage);closesocket(socketTmp);}
   客户端就一个函数完成了一次通信。在这里IP地址为何用127.0.0.1呢?使用这个IP地址,服务器端和客户端就能运行在同一台机器上,这样调试方便多了。当然你可以在你朋友的机器上运行Server程序(本人在局域网中测试过),在自己的机器上运行Client程序,当然输入的IP地址就该是你朋友机器的IP地址了。简单的理论和实践都说了,现在Socket编程不神秘了吧?希望对你有些帮助。

转载于:https://www.cnblogs.com/Solomon-xm/p/9446770.html

揭开Socket编程的面纱相关推荐

  1. Raw Socket和Socket编程

    1.原始套接字(raw socket) 1.1 原始套接字工作原理与规则          原始套接字是一个特殊的套接字类型,它的创建方式跟TCP/UDP创建方法几乎是 一摸一样,例如,通过 CODE ...

  2. Java Socket编程----通信是这样炼成的

    转载自 Java Socket编程----通信是这样炼成的 Java最初是作为网络编程语言出现的,其对网络提供了高度的支持,使得客户端和服务器的沟通变成了现实,而在网络编程中,使用最多的就是Socke ...

  3. Linux调试私房菜(四)揭开链接器的面纱、汇编语言的内嵌编程

    七.揭开链接器的面纱(上) 1. 问题 源文件被编译后生成目标文件,这些目标文件如何生存最终的可执行程序? 2. 链接器的意义 链接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块之间能 ...

  4. 揭开木马的神秘面纱 2

    揭开木马的神秘面纱zz 2 离冰河二的问世已经快一年了,大家对于木马这种远程控制软件也有了一定的认 识,比如:他会改注册表,他会监听端口等等,和一年前几乎没有人懂得木马是什么东   西相比,这是一个质 ...

  5. 了解黑客的关键工具---揭开Shellcode的神秘面纱

    2019独角兽企业重金招聘Python工程师标准>>> ref:  http://zhaisj.blog.51cto.com/219066/61428/ 了解黑客的关键工具---揭开 ...

  6. 未来已来?揭开量子计算机的神秘面纱

    从第一台现代计算机ENIAC的诞生到个人PC时代的降临,从互联网概念的提出到移动互联的疾跑,在这个信息年代里,变革正以前所未有的速度改变着我们熟悉的世界.熟悉的生活. 作为个人,我们早已习惯于智能计算 ...

  7. 【翻译】揭开HTML5的神秘面纱

    写在前面的话: 这篇文章摘自Mozilla官网,主要针对HTML5和本地应用发表了一些.没有设计到技术,所以基本是逐字翻译,但愿我蹩脚的英语水平能把大师的 Chris Heilmann的思想整理明白. ...

  8. 揭开 LVS 神秘的面纱

    文章目录 揭开 LVS 神秘的面纱 一 前言 二 认识 LVS 三 了解三种模式 3.1 Virtual Server via Network Address Translation(VS/NAT) ...

  9. 揭开木马的神秘面纱 1

    揭开木马的神秘面纱 1 前言 在网上,大家最关心的事情之一就是木马:最近出了新的木马吗?木马究竟能实现 哪些功能?木马如何防治?木马究竟是如何工作的?本文试图以我国最著名的木马之  - 冰河为例,向大 ...

最新文章

  1. dba的前景_运维、测试、程序员,这些技术岗位哪个更有前景?
  2. 机试指南第二章-经典入门-查找例题自解
  3. 程序员不满薪资拒绝offer,HR怒称:估计你一辈子就是个程序员了!
  4. python高手养成_Python用PyQt5制作颜色对话框,PyQt图形界面编程之QColorDialog
  5. 编译原理 编译器自动生成工具
  6. 玩客云pc端_玩客云下载-玩客云电脑版下载-华军软件园
  7. 算法竞赛入门经典(第2版)—索引
  8. 液压系统仿真软件_利用仿真软件判断系统稳定
  9. 大数据相关面试题整理-带答案
  10. 群英传内推第001期
  11. 百度404.html,百度标准死链(404页面)官方文档全解析
  12. c语言编程运动会分数统计系统,东华大学数据结构设计C语言运动会分数统计系统...
  13. 小武学fpgastep4
  14. 北京市211学校计算机专业,北京较容易考的2所211大学,王牌专业实力强悍,学生不愁就业...
  15. 不入耳式蓝牙耳机什么牌子好、最好的骨传导耳机推荐
  16. 【BZOJ 2243】染色
  17. 云南省二级c计算机考试试题,2014云南省计算机等级考试试题 二级C试题最新考试试题库(完整版)...
  18. 跟益达学Solr5之使用MMSeg4J分词器
  19. android下雨动画效果,Android 自定义View(二) 下雨效果
  20. Win10 1803 (17134)找回控制面板语言设定的方法

热门文章

  1. windows server 2008 - 创建域和本机用户
  2. XE3随笔6:SuperObject 的 JSON 对象中还可以包含 方法
  3. C-二维数组,多维数组
  4. 对于表列数据类型选择的一点思考
  5. 配置GoldenGate源端Manager参数
  6. Ubuntu 11.10 开机让 Varnish 跟随 Nginx 一起启动
  7. 创建一个属于自己的名称空间.
  8. JAVA调用R语言之Rserve
  9. asp.net html 加密解密,三种方法还原ASP.NET可逆加密内容
  10. android ios 上传图片到服务器,.net 接收ios, android的上传图片