1:网络中进程之间如何通信

  为了实现进程之间通信,首要解决的问题是如何唯一标识一个进程,在本地可以通过进程PID来唯一标识一个进程,但是在网络中则是行不通的,其实TCP/IP协议族已经帮我们解决了这个问题,网络层的"ip 地址"可以唯一标识网络中的主机,而"传输层的 协议+端口"可以唯一标识主机中的应用程序(进程)。这样利用(ip地址,谢谢,端口)就可以标识网络中的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。而现在几乎所有网络应用程序都是采用socket来通信的,那么什么是socket呢?

2:套接字(socket)

  socket起源于Unix,而Unix/Linux基本哲学之一就是"一切皆文件",都可以用"打开Open -> 读写write/read ->关闭close"模式来操作,socket就是该模式的一个实现,socket就是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭),说白了Socket就是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。socket把复杂的TCP/IP协议族隐藏在socket接口后面,对用户来说就是一组简单的接口。让socket去组织数据,以符合指定的协议。

  随着Unix的应用推广,套接字有被引进了windows等操作系统,套接字通常只与同一区域的套接字交换数据,windows只支持一个通信区域,网际域(AF_INET),这个域被使用网际协议簇的通信进程。

3:客户机/服务器模式

  在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户机/服务器模式(client/server),即客户向服务器提出请求,服务器接受到请求后提出相应的服务。

服务器:

 (1):首先服务器先要启动,打开一个通信通道并告知本机,它愿意在某一个地址和端口上接收客户请求。

 (2):等待客户请求到达该端口。

 (3):接收服务请求,处理该客户请求,服务完成后,关闭此进程与客户的通信链路,并终止。

 (4):返回第二步,等待另一个客户请求

 (5):关闭服务器

客户方:

 (1):打开一个通信通道,并连接到服务器所在的主机特定的端口。

 (2):向服务器发送请求,等待并接收应答,继续提出请求。

 (3):请求结束后关闭通信信道并终止

4:基于TCP(面向连接)的socket编程

  

服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listlen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了,客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。

5:基于UDP(面向无连接)的socket编程

  

服务器先创建socket,将socket绑定(bind)一个本地地址和端口上,等待数据传输(recvfrom).这个时候如果有个客户端创建socket,并且向服务器发送数据(sendto),服务器就建立了连接,实现了数据的通信,连接结束后关闭连接.

6:UDP例子

  Server端

  1. //注:需要在stdafx.h 里面添加 #pragma comment(lib, "ws2_32.lib")
  2. #include"stdafx.h"
  3. #include <winsock2.h>
  4. #include <ws2tcpip.h>
  5. #include <stdio.h>
  6. #include <windows.h>
  7. using namespace std;
  8.  
  9. #pragma comment(lib, "ws2_32.lib") //add ws2_32.lib
  10.  
  11. int main()
  12. {
  13. WORD wVersionRequested;
  14. WSADATA wsaData;
  15. int err;
  16.  
  17. wVersionRequested = MAKEWORD(, );
  18.  
  19. err = WSAStartup(wVersionRequested, &wsaData);
  20. if (err != )
  21. {
  22. printf("WSAStartup failed with error: %d\n", err);
  23. return ;
  24. }
  25.  
  26. if (LOBYTE(wsaData.wVersion) != || HIBYTE(wsaData.wVersion) != )
  27. {
  28. printf("Could not find a usable version of Winsock.dll\n");
  29. WSACleanup();
  30. return ;
  31. }
  32. else
  33. {
  34. printf("The Winsock 2.2 dll was found okay\n");
  35. }
  36.  
  37. SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM, ); //创建一个socket句柄;
  38. if( sockSrv == INVALID_SOCKET )
  39. {
  40. printf("socket() fail:%d\n",WSAGetLastError());
  41. return -;
  42. }
  43.  
  44. SOCKADDR_IN addrServ;
  45. memset(&addrServ,,sizeof(addrServ));
  46. addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
  47. addrServ.sin_family = AF_INET;
  48. addrServ.sin_port = htons(); //从"主机字节顺序" 转变为 "网络字节顺序"
  49.  
  50. err = bind(sockSrv,(SOCKADDR*)&addrServ,sizeof(SOCKADDR)); //把socket 绑定到指定地址上
  51. if( err != )
  52. {
  53. printf("bind()fail:%d\n",WSAGetLastError());
  54. return -;
  55. }
  56.  
  57. SOCKADDR_IN addrClient;
  58. memset(&addrClient,,sizeof(addrClient)); //在设置每个地址成员之前,整个addr结构应该被初始化0;
  59. int length = sizeof(SOCKADDR);
  60. char recvBuf[];
  61. printf("waiting for client connect!!!!\n");
  62. recvfrom(sockSrv,recvBuf,,,(SOCKADDR*)&addrClient,&length);
  63.  
  64. printf("recvfrom client:: %s\n",recvBuf);
  65.  
  66. closesocket(sockSrv);
  67.  
  68. WSACleanup();
  69.  
  70. system("PAUSE");
  71. return ;
  72. }

Client端

  1. // 注:需要在stdafx.h 里面添加 #pragma comment(lib, "ws2_32.lib")
  2. //
  3. #include"stdafx.h"
  4. #include <winsock2.h>
  5. #include <ws2tcpip.h>
  6. #include <stdio.h>
  7. #include <windows.h>
  8. using namespace std;
  9.  
  10. #pragma comment(lib, "ws2_32.lib") //add ws2_32.lib
  11.  
  12. int main()
  13. {
  14. WORD wVersionRequested;
  15. WSADATA wsaData;
  16. int err;
  17.  
  18. wVersionRequested = MAKEWORD(, );
  19.  
  20. err = WSAStartup(wVersionRequested, &wsaData);
  21. if (err != )
  22. {
  23. printf("WSAStartup failed with error: %d\n", err);
  24. return ;
  25. }
  26.  
  27. if (LOBYTE(wsaData.wVersion) != || HIBYTE(wsaData.wVersion) != )
  28. {
  29. printf("Could not find a usable version of Winsock.dll\n");
  30. WSACleanup();
  31. return ;
  32. }
  33. else
  34. {
  35. printf("The Winsock 2.2 dll was found okay\n");
  36. }
  37.  
  38. SOCKET sockClient = socket(AF_INET,SOCK_DGRAM, );
  39.  
  40. SOCKADDR_IN addrServ;
  41. memset(&addrServ,,sizeof(addrServ));
  42. addrServ.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
  43. addrServ.sin_family = AF_INET;
  44. addrServ.sin_port = htons();
  45. printf("begin to send data to server::Hello\n");
  46. sendto(sockClient,"Hello\n",strlen("Hello\n")+,,(SOCKADDR*)&addrServ,sizeof(SOCKADDR));
  47.  
  48. closesocket(sockClient);
  49.  
  50. system("PAUSE");
  51. WSACleanup();
  52.  
  53. return ;
  54. }

输出的结果为:

 7:TCP例子

Server端

  1. #include"stdafx.h"
  2. #include <winsock2.h>
  3. #include <iostream>
  4.  
  5. #include <string.h>
  6. using namespace std;
  7.  
  8. #pragma comment(lib, "ws2_32.lib") //add ws2_32.lib
  9.  
  10. const int DEFAULT_PORT = ;
  11. int main(int argc,char* argv[])
  12. {
  13.  
  14. WORD wVersionRequested;
  15. WSADATA wsaData;
  16. int err,iLen;
  17. wVersionRequested = MAKEWORD(,);
  18.  
  19. err = WSAStartup(wVersionRequested,&wsaData);
  20. if( err!= )
  21. {
  22. printf("WSAStartup failed with error: %d\n", err);
  23. return -;
  24. }
  25. if ( LOBYTE(wsaData.wVersion) != || HIBYTE(wsaData.wVersion) != )
  26. {
  27. printf("Could not find a usable version of Winsock.dll\n");
  28. WSACleanup();
  29. return ;
  30. }
  31. else
  32. {
  33. printf("The Winsock 2.2 dll was found okay\n");
  34. }
  35.  
  36. SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,);
  37. if( sockSrv == INVALID_SOCKET )
  38. {
  39. printf("socket() fail:%d\n",WSAGetLastError());
  40. return -;
  41. }
  42.  
  43. SOCKADDR_IN addrSrv;
  44. memset(&addrSrv,,sizeof(addrSrv));
  45. addrSrv.sin_family = AF_INET;
  46. addrSrv.sin_addr.s_addr = htonl(INADDR_ANY);
  47. addrSrv.sin_port = htons(DEFAULT_PORT);
  48.  
  49. err = bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
  50. if( err != )
  51. {
  52. printf("bind()fail:%d\n",WSAGetLastError());
  53. return -;
  54. }
  55.  
  56. err = listen( sockSrv, );//listen函数的第一个参数即为要监听的socket描述字,第二个参数为相应socket可以排队的最大连接个数
  57. if( err != )
  58. {
  59. printf("listen()fail:%d\n",WSAGetLastError());
  60. return -;
  61. }
  62. printf("Server waitting...!!!!!\n");
  63. SOCKADDR_IN addrClt;
  64. int len = sizeof(SOCKADDR);
  65. memset(&addrClt,,len);
  66.  
  67. while()
  68. {
  69. SOCKET sockConn = accept(sockSrv,(SOCKADDR*)&addrClt,&len);
  70. char sendBuf[],hostname[];
  71. if( gethostname(hostname,) != )
  72. {
  73. strcpy_s(hostname,strlen("None")+,"None");
  74. }
  75. sprintf_s(sendBuf,sizeof(sendBuf),"Welecome %s connected to %s!",inet_ntoa(addrClt.sin_addr),hostname);
  76.  
  77. err = send(sockConn,sendBuf,strlen(sendBuf)+,);
  78.  
  79. char recvBuf[]="\0";
  80. iLen = recv(sockConn,recvBuf,,);
  81.  
  82. recvBuf[iLen]='\0';
  83. printf(recvBuf);
  84.  
  85. closesocket(sockConn);
  86. }
  87.  
  88. closesocket(sockSrv);
  89.  
  90. WSACleanup();
  91. return ;
  92. }

Client端

  1. // client.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include"stdafx.h"
  4. #include <winsock2.h>
  5. #include <iostream>
  6.  
  7. #include <string.h>
  8. using namespace std;
  9.  
  10. #pragma comment(lib, "ws2_32.lib")
  11.  
  12. const int DEFAULT_PORT = ;
  13. int main(int argc,char* argv[])
  14. {
  15.  
  16. WORD wVersionRequested;
  17. WSADATA wsaData;
  18. int err,iLen;
  19. wVersionRequested = MAKEWORD(,);
  20.  
  21. err = WSAStartup(wVersionRequested,&wsaData); //load win socket
  22. if( err != )
  23. {
  24. printf("WSAStartup failed with error: %d\n", err);
  25. return -;
  26. }
  27.  
  28. SOCKET sockClt = socket(AF_INET,SOCK_STREAM,);
  29. if( sockClt == INVALID_SOCKET )
  30. {
  31. printf("socket() fail:%d\n",WSAGetLastError());
  32. return -;
  33. }
  34.  
  35. SOCKADDR_IN addrSrv;
  36. memset(&addrSrv,,sizeof(addrSrv));
  37. addrSrv.sin_family = AF_INET;
  38. addrSrv.sin_addr.s_addr = inet_addr("127.0.0.1");
  39. addrSrv.sin_port = htons(DEFAULT_PORT);
  40.  
  41. err = connect(sockClt,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
  42.  
  43. if(err ==INVALID_SOCKET)
  44. {
  45. printf("connect()fail:%d\n",WSAGetLastError());
  46. return -;
  47. }
  48.  
  49. char sendBuf[],hostname[];
  50. if( gethostname(hostname,) != ) //如果没有错误的时候gethostname会返回0;
  51. {
  52. strcpy_s(hostname,strlen("None")+,"None");
  53. }
  54. strcpy_s(sendBuf,strlen(hostname)+,hostname);
  55. strcat_s(sendBuf,sizeof(sendBuf)," have connected to you!");
  56. err = send(sockClt,sendBuf,strlen(sendBuf)+,);
  57.  
  58. char recvBuf[]="\0";
  59. iLen = recv(sockClt,recvBuf,,);
  60.  
  61. if( iLen == )
  62. {
  63. return -;
  64. }
  65. else if( iLen == SOCKET_ERROR )
  66. {
  67. printf("recv() fail:%d\n",WSAGetLastError());
  68. return -;
  69. }
  70. else
  71. {
  72. recvBuf[iLen] = '\0';
  73. printf(recvBuf);
  74. printf("\n");
  75. }
  76. closesocket(sockClt);
  77.  
  78. WSACleanup();
  79. system("PAUSE");
  80. return ;
  81. }

输出的结果为

Windows Socket的UDP和TCP编程介绍的更多相关文章

  1. 基于Socket的UDP和TCP编程介绍

    一.概述 TCP(传输控制协议)和UDP(用户数据报协议是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议. TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流 ...

  2. 初识-----基于Socket的UDP和TCP编程及测试代码

    一.概述 TCP(传输控制协议)和UDP(用户数据报协议是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议. TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流 ...

  3. Python基础教程之udp和tcp协议介绍

    Python基础教程之udp和tcp协议介绍 UDP介绍 UDP --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议.UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但 ...

  4. socket 、 udp 和 tcp

    强调一点: socket . udp . tcp之间的区别. socket只是一种套接字,就是两台电脑两端的东西,中间传输以流的格式进行.  IBEO好像是TCP/IP ,  无论对于TCP和UDP, ...

  5. 【Windows socket+IP+UDP+TCP】网络基础

    Windows Socket+网络      Winsock是 Windows下套接字标准.          Winsock 编程分为UDP[Windows socket + UDP],TCP[Wi ...

  6. python | 网络编程(socket、udp、tcp)

    一.套接字 socket 1.1 作用:实现不同主机间的进程间通信(不同电脑.手机等设备之间收发数据) 1.2 分类:udp.tcp 1.3 创建 socket import socket socke ...

  7. Linux C Socket TCP编程介绍及实例

    转自:https://blog.csdn.net/lell3538/article/details/53335231 { printf("向服务器发送数据:%s\n",sendbu ...

  8. python3(socket 实现udp,tcp套接字编程)

    #coding=utf-8 #客户端程序TCP 连接 import socket s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connec ...

  9. socket实现udp与tcp通信-java

    1.简单介绍Socket Socket套接字 网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字. 通信的两端都有Socket. 网络通信其实就是Socket间的通信. 数 ...

随机推荐

  1. SpringBoot集成redis的key,value序列化的相关问题

    使用的是maven工程 springBoot集成redis默认使用的是注解,在官方文档中只需要2步; 1.在pom文件中引入即可 <dependency> <groupId>o ...

  2. Webpack模块的导出以及之间的依赖引用

    一. 模块化开发模块化开发说白了就不必在html页面,引用所有的js文件.所有的js文件都进行模块化设置,模块之间可以相互引用.Webpack模块化开发是使用module.exports进行相关方法和 ...

  3. Python中四种样式的99乘法表

    1.常规型. #常规型 i=1 while i<=9: j=1 while j<=i: print(''%d*%d=%2d''%(i,j,i*j),end='') i+=1 #等号只是用来 ...

  4. WCF跨域解决方法及一些零碎的东西。

    之前发过一篇随笔,说的WCF配置文件配置问题.里面也配了跨域支持,但是jsoncollback只支持Get请求,Post请求是解决不了,所以这里把真正的WCF跨域问题贴出来. 话不多说,直接帖配置文件 ...

  5. js和jquery判断checkbox是否被选中

    js判断: if(document.getElementById("checkboxID").checked){ alert("checkbox is checked&q ...

  6. css3控制div上下跳动

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. 指令-arContentedit-可编辑的高度自适应的div

    <div  ar-contentedit="true" contenteditable="true"  contenteditable="pla ...

  8. transient 与 volatile 笔记

    1. transient 词义:瞬间的,短暂的 首先说说"序列化",把一个对象的表示转化为字节流的过程称为串行化(也称为序列化,serialization),从字节流中把对象重建出 ...

  9. Alpha冲刺Day9

    Alpha冲刺Day9 一:站立式会议 今日安排: 经过为期5天的冲刺,基本完成企业人员模块的开发.因第三方机构与企业存在委托的关系.第三方人员对于风险的自查.风险列表的展示以及自查风险的统计展示(包 ...

  10. 1013团队Beta冲刺day6

    项目进展 李明皇 今天解决的进度 进行前后端联动调试 明天安排 完善程序运行逻辑 林翔 今天解决的进度 服务器端发布消息,删除消息,检索消息,个人发布的action 明天安排 图片功能遇到问题,微信小 ...