复习一下,先复习下简单的套接字。

好记性不如烂笔头,烂笔头不如烂键盘,烂键盘好过没键盘。

Windows下.........................................................................................................................

类型:

流式套接字(SOCK_STREAM):套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复送,并按顺序接收。TCP

数据报式套接字(SOCK_DGRAM:提供无连接服务,数据包以独立包形式发送,不提供无措保证,数据可能丢失或重复,并且接收顺序混乱。UDP

原始套接字(SOCK_RAW:原始套接字与流式和数据报套接字的区别在于:原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送的数据必须使用原始套接

常用基本函数:

  • int WSAStartup(WORD,& WSADATA)

说明:加载套接字库,加载成功返回0。

参数一:指定套接字版本,高位指定主版本,低位指定副版本,可以利用MAKEWORD(x,y)生成,其中x是高位,y是低位。

参数二:用于接收WSAStartup加载的套接字库版本信息。WSADATA结构体中,第一个成员代表主版本,第二个成员代表副版本。

  • int socket(int af, int type, int protocol)

说明:创建套接字。成功返回套接字描述符。失败返回INVALID_SOCKET。

参数一:指定地址族,对于TCP/IP协议 ,只能为AF_INET也可以写为PF_INET.

参数二:指定套接字类型,SOCK_STREAM为流式套接字(TCP),SOCK_DGRAM产生数据报套接字(UDP)。

参数三:指定与地址家族相关的协议,如果为0会自动分配一个合适的协议。

  • int bind( SOCKET sockaddr, const struct sockaddr FAR* my_addr,int addrlen)

说明:为套接字绑定本地地址,成功返回0,失败返回-1

参数一:通过socket()函数创建的套接字

参数二:指定的本地地址信息,类型为sockaddr结构指针变量

参数三:指定地址结构的长度,sizeof(sockaddr)

struct sockaddr {unsigned short sa_family; //指定地址族,必须为AF_INETchar sa_data[14];  //占位,指定协议相关具体地址信息};

为了方便地址填写,一般用sockaddr_in代替sockaddr,参数填写的时候进行强转即可

struct sockaddr_in {short int sin_family; //地址族 只能是AF_INETunsigned short int sin_port;   //指定端口号(要网字节序 使用函数htons()转化)struct in_addr sin_addr;  //套接字主机IP地址,用到in_addr结构体unsigned char sin_zero[8];   //填充数,使sockaddr_in和sockaddr的sizeof相等};

对于IP地址,如果指定为INADDR_ANY,则允许套接字向任何分配给本机机器的IP地址发送或接受数据,如果机器有多个网卡,可以简化应用程序的编写。

typedef struct in_addr {union {struct{ unsigned char s_b1,s_b2, s_b3,s_b4;} S_un_b;struct{ unsigned short s_w1, s_w2;} S_un_w;unsigned long S_addr;  // IP地址(网络字节序,利用htonl()转换)} S_un;} IN_ADDR;

inet_addr(“192.168.1.156”)会返回一个适合S_addr 的unsigned long类型,inet_ntoa(in_addr)则相反 ,会将一个in_addr结构体返回一个点分的字符串,”192.168.1.156”

  • int listen(int sockfd, int backlog)

说明:将套接字设置为监听模式,成功返回0,失败返回-1

参数一:套接字描述符socket()函数创建的套接字

参数而:等待连接队列的最大长度(并不是在一个端口连接数)

  • accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)

说明:等待客户连接,并接受客户连接。请求成功,返回一个相对于连接的新的套接字,原先的套接字,继续监听连接请求,失败返回INVALID_SOCKET

参数一:套接字描述符

参数二:保存发起连接的套接字的IP和端口信息,也利用sockaddr_in代替sockaddr

参数三:保存返回的套接字地址长度,必须要赋初值,sizeof(sockaddr)

  • int connect (SOCKET s, const struct sockaddr * name, int namelen )

说明:与指定套接字建立连接,成功返回0,失败返回SOCKET_ERROR,也就是-1.

参数一:套接字描述符

参数二:指定要连接的套接字的地址,也就是服务端的

参数三:地址长度

  • int send(SOCKET s, const char FAR *buf, int len, int flags) / sendto

说明:向指定套接字发送数据,send用于TCP连接,sento用于UDP连接,并且sendto多了两个参数,用来指定服务端的地址和长度。成功返回发送数据长度,失败返回SOCKET_ERROR

参数一:指定接收端套接字,即通过accept()接受的套接字

参数二:要发送的字符数据

参数三:带发送数据的长度

参数四:执行方式,影响send的调用行为,一般设为0

  • int recv(SOCKET s, char FAR *buf, int len, int flags) / recvfrom

说明:接收指定套接字数据,recv用于TCP连接,recvfrom用于UDP连接,并且recvfrom多了两个参数,用来指定服务端的地址和长度,并且接收地址长度的参数必须初始化。成功返回接收数据长度,失败返回-1

参数一:指定接收端的套接字

参数二:存储数据的缓冲区

参数三:缓冲区大小

参数四:执行方式

  • closesocket(socket)

说明:关闭套接字

  • WSACleanup()

说明:终止对套接字库的使用

  • int WSAGetLastError()  / GetLastError()

说明:返回一个int类型的Winsock错误代码,对于上述函数执行返回失败,都可以利用该函数进行捕捉错误。

TCP和UDP连接:

TCP:面向连接的,可靠的

(1)数据传输过程必须经过建立连接、维护连接和释放连接3个阶段

(2)在传输过程中,不需要携带目的主机的地址

(3)可靠,协议复杂,通信效率不低

UDP:面向无连接的,不可靠

(1)不需要连接

(2)每个分组都携带完整的目的主机地址,在系统中独立传送

(3)没有顺序控制,接收方的分组可能出现乱序、重复和丢失现象

(4)通信效率高,不可靠

TCP例子:

图片 哪儿来的?

服务端:

#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<iostream>
#include<winsock2.h>
using namespace std;int main()
{WORD word = MAKEWORD(2, 0);WSADATA wsaData;if (WSAStartup(word, &wsaData) != 0){printf("套接字库加载失败!\n");int err = GetLastError();printf("errNum = %d\n", err);return -1;}if (LOBYTE(wsaData.wVersion != 2) || HIBYTE(wsaData.wHighVersion != 0)){printf("套接字库加载失败!\n");WSACleanup();return -1;}int sockSrv = socket(AF_INET, SOCK_STREAM, 0);if (sockSrv == INVALID_SOCKET){printf("套接字创建失败!\n");int err = GetLastError();printf("errNum = %d\n", err);WSACleanup();return -1;}sockaddr_in addrSrv;addrSrv.sin_family = AF_INET;addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);addrSrv.sin_port = htons(6666);if (int res = bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR))!= 0){printf("套接字绑定失败!");int err = GetLastError();printf("errNum = %d\n", err);WSACleanup();return -1;}if (int res = listen(sockSrv, 5) != 0){printf("监听套接字失败!");int err = GetLastError();printf("errNum = %d\n", err);WSACleanup();return -1;}sockaddr_in addrClient;int addrlen;while (1){addrlen = sizeof(SOCKADDR);int sockClient = accept(sockSrv, (SOCKADDR*)&addrClient, &addrlen);if (sockClient == INVALID_SOCKET){printf("套接字连接失败!");int err = GetLastError();printf("errNum = %d\n", err);continue;}char sendBuf[200] = { 0 };char recvBuf[200] = { 0 };sprintf(sendBuf, "hello ,this is %s", inet_ntoa(addrSrv.sin_addr));send(sockClient, sendBuf, strlen(sendBuf) + 1, 0);recv(sockClient, recvBuf, sizeof(recvBuf), 0);printf("%s\n", recvBuf);closesocket(sockClient);}closesocket(sockSrv);WSACleanup();system("pause");return 0;
}

客户端:

#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<iostream>
#include<winsock2.h>
using namespace std;int main()
{WORD word = MAKEWORD(2, 0);WSADATA wsaData;if (WSAStartup(word, &wsaData) != 0){printf("套接字库加载失败!\n");int err = GetLastError();printf("errNum = %d\n", err);return -1;}if (LOBYTE(wsaData.wVersion != 2) || HIBYTE(wsaData.wHighVersion != 0)){printf("套接字库加载失败!\n");WSACleanup();return -1;}int sockClient = socket(AF_INET, SOCK_STREAM, 0);if (sockClient == INVALID_SOCKET){printf("套接字创建失败!\n");int err = GetLastError();printf("errNum = %d\n", err);WSACleanup();return -1;}sockaddr_in addrSrv;addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");addrSrv.sin_family = AF_INET;addrSrv.sin_port = htons(6666);if (connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) != 0){printf("套接字连接失败!\n");int err = GetLastError();printf("errNum = %d\n", err);WSACleanup();return -1;}char recvBuf[200] = { 0 };char sendBuf[200] = { 0 };int recvLen = recv(sockClient, recvBuf, sizeof(recvBuf), 0);printf("%s\n",recvBuf);sprintf(sendBuf," my name is zhangsan");send(sockClient,sendBuf,strlen(sendBuf)+1,0);closesocket(sockClient);WSACleanup();system("pause");return 0;
}

UDP例子:

服务端:

#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<iostream>
#include<winsock2.h>
using namespace std;int main()
{WORD word = MAKEWORD(2, 0);WSADATA wsaData;if (WSAStartup(word, &wsaData) != 0){printf("套接字库加载失败!\n");int err = GetLastError();printf("errNum = %d\n", err);return -1;}if (LOBYTE(wsaData.wVersion != 2) || HIBYTE(wsaData.wHighVersion != 0)){printf("套接字库加载失败!\n");return -1;WSACleanup();}int sockSrv = socket(AF_INET, SOCK_DGRAM, 0);if (sockSrv == INVALID_SOCKET){printf("创建套接字失败!\n");int err = GetLastError();printf("errNum = %d\n", err);WSACleanup();return -1;}sockaddr_in addrSrv;addrSrv.sin_family = AF_INET;addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);addrSrv.sin_port = htons(6000);if (bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) != 0){printf("套接字绑定失败!\n");int err = GetLastError();printf("errNum = %d\n", err);WSACleanup();return -1;}sockaddr_in addrClient;int addrlen = sizeof(SOCKADDR);while (1){char sendBuf[200] = { 0 };char recvBuf[200] = { 0 };int recvLen = recvfrom(sockSrv, recvBuf, sizeof(recvBuf), 0, (SOCKADDR*)&addrClient, &addrlen);if (recvLen > 0){printf("%s\n", recvBuf);}sprintf(sendBuf, "hello ,this is %s", inet_ntoa(addrSrv.sin_addr));sendto(sockSrv, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR*)&addrClient, addrlen);}closesocket(sockSrv);WSACleanup();system("pause");return 0;
}

客户端:

#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<iostream>
#include<winsock2.h>
using namespace std;int main()
{WORD word = MAKEWORD(2, 0);WSADATA wsaData;if (WSAStartup(word, &wsaData) != 0){printf("套接字库加载失败!\n");int err = GetLastError();printf("errNum = %d\n", err);return -1;}if (LOBYTE(wsaData.wVersion != 2) || HIBYTE(wsaData.wHighVersion != 0)){printf("套接字库加载失败!\n");return -1;WSACleanup();}int sockClient = socket(AF_INET, SOCK_DGRAM, 0);if (sockClient == INVALID_SOCKET){printf("创建套接字失败!\n");int err = GetLastError();printf("errNum = %d\n", err);WSACleanup();return -1;}sockaddr_in addrSrv;addrSrv.sin_family = AF_INET;addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");addrSrv.sin_port = htons(6000);int addrlen = sizeof(SOCKADDR);char sendBuf[200] = { 0 };char recvBuf[200] = { 0 };sprintf(sendBuf, "my name is demaxiya", inet_ntoa(addrSrv.sin_addr));sendto(sockClient, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR*)&addrSrv, addrlen);int recvLen = recvfrom(sockClient, recvBuf, sizeof(recvBuf), 0,(SOCKADDR*)&addrSrv, &addrlen);if (recvLen > 0){printf("%s\n", recvBuf);}closesocket(sockClient);WSACleanup();system("pause");return 0;
}

错误不知道有没有,有也别慌。

网络编程:套接字 socket相关推荐

  1. 网络编程套接字Socket

    首先理解源IP地址和目的IP地址 在IP数据包头部中, 有两个IP地址, 分别叫做源IP地址, 和目的IP地址 了解端口号 端口号(port)是传输层协议的内容 端口号是一个32位的整数 端口号用来标 ...

  2. 网络编程套接字(四)

    网络编程套接字(四) 文章目录 网络编程套接字(四) 一.实现tcp服务器多用户版本(多进程.多线程.线程池版本) 一.实现tcp服务器多用户版本(多进程.多线程.线程池版本) tcp_process ...

  3. 网络编程套接字(三)

    网络编程套接字(三) 文章目录 网络编程套接字(三) 一.实现简单的Tcp服务器(单用户) 一.实现简单的Tcp服务器(单用户) tcp_socket.hpp #pragma once #includ ...

  4. 网络编程套接字(二)

    网络编程套接字(二) 文章目录 网络编程套接字(二) 一.简单的UDP网络程序 一.简单的UDP网络程序 封装udp_socket #pragma once #include <cstdio&g ...

  5. 网络编程套接字(一)

    网络编程套接字(一) 文章目录 网络编程套接字(一) 一.基础知识 二.sock编程接口 一.基础知识 1. 理解源IP地址和目的IP地址 在IP数据包头部中,有两个IP地址,分别叫源IP地址和目的I ...

  6. 详细讲解 —— 网络编程套接字(Java EE初阶)

    网络编程套接字 1 认识网络编程套接字 2 UDP 数据报套接字编程 2.1 UPD服务端 2.1 UDP客户端 2.3 结果测试 3 TCP流套接字编程 3.1 TCP服务端 3.2 TCP客户端 ...

  7. 【javaEE】网络编程套接字

    To u&me: 努力经营当下,直至未来明朗 文章目录 前言 一.网络编程(没时间可以跳过) 一)网络编程了解 二)相关基本概念 二.Socket套接字 三.数据报套接字通信(UDP) 写一个 ...

  8. Java网络编程套接字

    文章目录 1.网络编程基础 2.什么是网络编程 3.网络编程中的基本概念 3.1.发送端和接收端 3.2 请求和响应 3.3 客户端和服务端 3.4 常见的客户端服务端模型 4.Socket套接字 4 ...

  9. UNIX网络编程---套接字编程简介(三)

    UNIX网络编程---套接字编程简介 一.概述 从这里开始正式开始网络编程之旅,所有的函数都是基本的库函数.这些都是网络编程的基础.Come on!!!! 二.套接字地址结构 大多数套接字函数都需要一 ...

  10. 【网络编程套接字(一)】

    网络编程套接字(一) 理解源IP地址和目的IP地址 理解源MAC地址和目的MAC地址 理解源端口号和目的端口号 PORT VS PID 认识TCP协议和UDP协议 网络字节序 socket编程接口 s ...

最新文章

  1. Jsoncpp 使用方法解析
  2. 声腔设计中无前腔的影响
  3. python装饰器的顺序_python中多个装饰器的执行顺序详解
  4. C语言中printf输出特殊字符(“%d“或者“\n“)
  5. 作业6--第3、4、5天进度
  6. js中的var和new
  7. jnid中mysql的驱动类_JDBC与JNDI的区别
  8. 2022山东理工大学pta程序设计---实验四1---13题解
  9. [Matlab]绘图颜色
  10. 团队协作工具-版本控制软件SVN、Git、码云
  11. stm32指纹考勤机 (程序源码包括app程序+pcb电路图+原件清单)
  12. CK11N改标准价格
  13. iOS编译cURL库并链接darwinssl,zlib,c-ares库操作步骤
  14. win10最简单定时关机命令
  15. 计算机应用基础试题文件夹,计算机应用基础试题及参考答案
  16. 软件工程 - 项目管理
  17. javascript面向对象(三):class语法详解
  18. VHDL中的signal(信号)variable(变量)的定义与赋值
  19. 计算机毕设Python+Vue智能仓储进出货管理系统(程序+LW+部署)
  20. 中兴面试-guozhijun20160628

热门文章

  1. 曙光服务器进去系统后黑屏,大明:电脑进入win7系统后黑屏的解决办法
  2. “红遍全球”的恶意软件 Mirai 换了个新马甲,这次瞄上我国2亿多台IoT设备
  3. Ci521 13.56MHz非接触式读写器芯片(AB卡,低成本)
  4. 手机电池充电时间计算方法
  5. 4 种在 Linux 中检查默认网关或者路由器 IP 地址的方法
  6. 中国香港DHB Global公司首席执行官道格拉斯•科利: 大数据是一个历史性机遇...
  7. 天猫数据分析软件(天猫销售数据如何查询)
  8. 2020年月份间销售额波动原因定位
  9. [深入研究4G/5G/6G专题-60]: Nokia如何让小基站即插即用
  10. ES8323S双通道DAC单通道ADC可单声道录音多路选择