当前位置: 首页 > news >正文

定州市建设局网站网站建设 价格

定州市建设局网站,网站建设 价格,做石材网站步骤,宜宾网站建设北斗网络此为牛客Linux C课程和黑马Linux系统编程笔记。 1. 什么是socket 所谓 socket#xff08;套接字#xff09;#xff0c;就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。 一个套接字就是网络上进程通信的一端#xff0c;提供了应用层进程利用网络协议交换…此为牛客Linux C课程和黑马Linux系统编程笔记。 1. 什么是socket 所谓 socket套接字就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。 一个套接字就是网络上进程通信的一端提供了应用层进程利用网络协议交换数据的机制。从所处 的地位来讲套接字上联应用进程下联网络协议栈是应用程序通过网络协议进行通信的接口 是应用程序与网络协议根进行交互的接口。 socket 可以看成是两个网络应用程序进行通信时各自通信连接中的端点这是一个逻辑上的概 念。它是网络环境中进程间通信的 API也是可以被命名和寻址的通信端点使用中的每一个套接 字都有其类型和一个与之相连进程。通信时其中一个网络应用程序将要传输的一段信息写入它所在 主机的 socket 中该 socket 通过与网络接口卡NIC相连的传输介质将这段信息送到另外一台 主机的 socket 中使对方能够接收到这段信息。socket 是由 IP 地址和端口结合的提供向应用 层进程传送数据包的机制。 socket 本身有“插座”的意思在 Linux 环境下用于表示进程间网络通信的特殊文件类型。本质为 内核借助缓冲区形成的伪文件。既然是文件那么理所当然的我们可以使用文件描述符引用套接 字。与管道类似的Linux 系统将其封装成文件的目的是为了统一接口使得读写套接字和读写文 件的操作一致。区别是管道主要应用于本地进程间通信而套接字多应用于网络进程间数据的传 递。 套接字的内核实现较为复杂不宜在学习初期深入学习。 在TCP/IP协议中“IP地址TCP或UDP端口号”唯一标识网络通讯中的一个进程。“IP地址端口号”就对应一个socket。欲建立连接的两个进程各自有一个socket来标识那么这两个socket组成的socket pair就唯一标识一个连接。因此可以用Socket来描述网络连接的一对一关系。 套接字通信原理如下图所示 在网络通信中套接字一定是成对出现的。一端的发送缓冲区对应对端的接收缓冲区。我们使用同一个文件描述符索发送缓冲区和接收缓冲区。 2. socket相关函数 2.1 socket( )函数 #include sys/types.h #include sys/socket.h #include arpa/inet.h // 包含了这个头文件上面两个就可以省略 int socket(int domain, int type, int protocol);功能创建一个套接字 参数 domain: 协议族 AF_INET : ipv4 AF_INET6 : ipv6 AF_UNIX, AF_LOCAL : 本地套接字通信进程间通信 type: 通信过程中使用的协议类型 SOCK_STREAM : 流式协议 SOCK_DGRAM : 报式协议 protocol : 具体的一个协议。一般写0 SOCK_STREAM : 流式协议默认使用 TCP SOCK_DGRAM : 报式协议默认使用 UDP 返回值 成功返回文件描述符操作的就是内核缓冲区。失败-1 socket( )打开一个网络通讯端口如果成功的话就像open()一样返回一个文件描述符应用程序可以像读写文件一样用read/write在网络上收发数据如果socket()调用出错则返回-1。对于IPv4domain参数指定为AF_INET。对于TCP协议type参数指定为SOCK_STREAM表示面向流的传输协议。如果是UDP协议则type参数指定为SOCK_DGRAM表示面向数据报的传输协议。protocol参数的介绍从略指定为0即可。 2.2 bind( )函数 #include sys/types.h #include sys/socket.h #include arpa/inet.h // 包含了这个头文件上面两个就可以省略 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); // socket命名功能绑定将文件描述符fd和本地的IP , 端口进行绑定 参数 sockfd : 通过socket()函数得到的文件描述符addr : 需要绑定的socket地址这个地址封装了ip和端口号的信息addrlen : 第二个参数结构体占的内存大小 返回值成功返回0失败返回-1, 设置errno 服务器程序所监听的网络地址和端口号通常是固定不变的客户端程序得知服务器程序的地址和端口号后就可以向服务器发起连接因此服务器需要调用bind绑定一个固定的网络地址和端口号。 bind()的作用是将参数sockfd和addr绑定在一起使sockfd这个用于网络通讯的文件描述符监听addr所描述的地址和端口号。上一篇讲过struct sockaddr *是一个通用指针类型addr参数实际上可以接受多种协议的sockaddr结构体而它们的长度各不相同所以需要第三个参数addrlen指定结构体的长度。 2.3 listen( )函数 #include sys/types.h #include sys/socket.h #include arpa/inet.h // 包含了这个头文件上面两个就可以省略 int listen(int sockfd, int backlog);功能监听这个socket上的连接 参数 sockfd : 通过socket()函数得到的文件描述符backlog : 未连接的和已经连接的和的最大值排队建立3次握手队列和刚刚建立3次握手队列的链接数和的最大值 典型的服务器程序可以同时服务于多个客户端当有客户端发起连接时服务器调用的accept()返回并接受这个连接如果有大量的客户端发起连接而服务器来不及处理尚未accept的客户端就处于连接等待状态listen()声明sockfd处于监听状态并且最多允许有backlog个客户端处于连接待状态如果接收到更多的连接请求就忽略。listen()成功返回0失败返回-1。 2.4 accept( )函数 #include sys/types.h #include sys/socket.h #include arpa/inet.h // 包含了这个头文件上面两个就可以省略 int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);功能接收客户端连接默认是一个阻塞的函数阻塞等待客户端连接 参数 sockfd : 用于监听的文件描述符addr : 传出参数记录了连接成功后客户端的地址信息ipportaddrlen : 传入传出参数值-结果 指定第二个参数的对应的内存大小传出第二个参数传出时的内存大小 返回值 成功返回一个新的socket文件描述符用于和客户端通信失败返回-1设置errno 三次握手完成后服务器调用accept()接受连接如果服务器调用accept()时还没有客户端的连接请求就阻塞等待直到有客户端连接上来。addr是一个传出参数accept()返回时传出客户端的地址和端口号。addrlen参数是一个传入传出参数value-result argument传入的是调用者提供的缓冲区addr的长度以避免缓冲区溢出问题传出的是客户端地址结构体的实际长度有可能没有占满调用者提供的缓冲区。如果给addr参数传NULL表示不关心客户端的地址。 一般来说我们的服务器程序结构是这样的 while (1) {cliaddr_len sizeof(cliaddr);connfd accept(listenfd, (struct sockaddr *)cliaddr, cliaddr_len);n read(connfd, buf, MAXLINE);......close(connfd); }整个是一个while死循环每次循环处理一个客户端连接。由于cliaddr_len是传入传出参数每次调用accept()之前应该重新赋初值。accept()的参数listenfd是先前的监听文件描述符而accept()的返回值是另外一个文件描述符connfd之后与客户端之间就通过这个connfd通讯最后关闭connfd断开连接而不关闭listenfd再次回到循环开头listenfd仍然用作accept的参数。accept()成功返回一个文件描述符出错返回-1。 一定要区分开connfd和listenfd的作用listenfd仅用于监听监听到了以后并不用它来进行信息传输。 2.5 connect( )函数 #include sys/types.h #include sys/socket.h #include arpa/inet.h // 包含了这个头文件上面两个就可以省略 int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);功能 客户端连接服务器 参数 sockfd : 用于通信的文件描述符addr : 客户端要连接的服务器的地址信息addrlen : 第二个参数的内存大小 返回值成功 0 失败 -1 客户端需要调用connect()连接服务器connect和bind的参数形式一致区别在于bind的参数是自己的地址而connect的参数是对方的地址。 3. 实现一个简单的服务端-客户端通信 接下来使用以上函数实现一个简单的服务端客户端通信实现将客户端的小写字母转换为大写字母。 3.1 通信流程 上图给了一个C/S模型网络编程的socket模板。 服务端 调用 socket() 建立套接字创建 struct sockaddr_in 并初始化服务端的ip和端口号调用 bind() 将第一步建立的套接字与第二步的sockaddr_inip和端口号绑定调用 listen() 设置最大同时发起连接数量调用 accept() 阻塞等待客户端发起连接调用 read() 读取客户端发出的数据处理请求调用 write() 发送数据给客户端调用 close() 关闭socket伪文件 客户端 调用 socket() 建立套接字调用 connect() 向客户端发起连接调用 write() 发送数据给服务端调用 read() 读取服务端返回的数据调用 close() 关闭socket伪文件 其中还有很多细节需要写代码的时候才能体会。 3.2 服务端 /*实现一个简单的服务器-客户端通信*/#include stdio.h #include unistd.h #include arpa/inet.h #include stdlib.h// 设定一个服务器端口号 #define SERV_IP 127.0.0.1 #define SERV_PORT 6666int main() {int lfd; // 用于监听的socket的文件描述符真正用于通信的套接字是接下来accept函数返回的cfd套接字struct sockaddr_in serv_addr;lfd socket(AF_INET, SOCK_STREAM, 0);serv_addr.sin_family AF_INET;// 注意这里要把小端存储的端口号改为大端存储serv_addr.sin_port htons(SERV_PORT); inet_pton(AF_INET, SERV_IP, serv_addr.sin_addr.s_addr); // 调用ip转换函数把字符串ip转化为网络字节序bind(lfd, (struct sockaddr * )serv_addr, sizeof(serv_addr));listen(lfd, 128); // 最大连接与待连接数设为128int cfd; // 已连接的客户端的socket的文件描述符, 以便一会儿read用struct sockaddr_in clie_addr; // 作为accept的第二个参数为传出参数传出的是客户端的sockadd_insocklen_t clie_addr_len sizeof(clie_addr); // 作为accept的第三个参数为传入传出参数之所以要单独定义出来是因为要传出cfd accept(lfd, (struct sockaddr *)clie_addr, clie_addr_len);while(1) {// 此处输出连接的客户端的ip和端口char clie_IP[BUFSIZ];printf(Client IP: %s, client port: %d\n, inet_ntop(AF_INET, clie_addr.sin_addr.s_addr, clie_IP, sizeof(clie_IP)),ntohs(clie_addr.sin_port));char buf[BUFSIZ]; // 给read使用存储读出的数据BUFSIZ宏是系统用来专门给buf赋长度的宏为8kDefault buffer sizeint len; // read的返回值是读入字符的长度len read(cfd, buf, sizeof(buf));// 把小写字母转化为大写字母int i;for(i 0; i len; i) {if(buf[i] z buf[i] a) {buf[i] - 32;}}write(cfd, buf, len);}close(lfd);close(cfd);return 0; }以上代码为突出主体没有写错误判断与错误提示。带错误提示代码如下 /*实现一个简单的服务器-客户端通信*/#include stdio.h #include unistd.h #include arpa/inet.h #include stdlib.h// 设定一个服务器端口号 #define SERV_IP 127.0.0.1 #define SERV_PORT 6666int main() {int lfd; // 用于监听的socket的文件描述符struct sockaddr_in serv_addr;int ret; // 用于错误检测lfd socket(AF_INET, SOCK_STREAM, 0);if(lfd -1) {perror(socket error);exit(1);}serv_addr.sin_family AF_INET;// 注意这里要把小端存储的端口号改为大端存储serv_addr.sin_port htons(SERV_PORT); inet_pton(AF_INET, SERV_IP, serv_addr.sin_addr.s_addr); // 调用ip转换函数把字符串ip转化为网络字节序ret bind(lfd, (struct sockaddr * )serv_addr, sizeof(serv_addr));if(ret -1) {perror(bind error);exit(1);}ret listen(lfd, 128); // 最大连接与待连接数设为128if(ret -1) {perror(listen error);exit(1);}int cfd; // 已连接的客户端的socket的文件描述符, 以便一会儿read用struct sockaddr_in clie_addr; // 作为accept的第二个参数为传出参数传出的是客户端的sockadd_insocklen_t clie_addr_len sizeof(clie_addr); // 作为accept的第三个参数为传入传出参数之所以要单独定义出来是因为要传出cfd accept(lfd, (struct sockaddr *)clie_addr, clie_addr_len);if(cfd -1) {perror(accept error);exit(1);}// 此处输出连接的客户端的ip和端口char clie_IP[BUFSIZ];printf(Client IP: %s, client port: %d\n, inet_ntop(AF_INET, clie_addr.sin_addr.s_addr, clie_IP, sizeof(clie_IP)),ntohs(clie_addr.sin_port));while(1) {char buf[BUFSIZ]; // 给read使用存储读出的数据BUFSIZ宏是系统用来专门给buf赋长度的宏为8kDefault buffer sizeint len; // read的返回值是读入字符的长度len read(cfd, buf, sizeof(buf));if(len -1) {perror(read error);exit(1);}// 把小写字母转化为大写字母int i;for(i 0; i len; i) {if(buf[i] z buf[i] a) {buf[i] - 32;}}ret write(cfd, buf, len);if(ret -1) {perror(write error);exit(1);}}close(cfd);close(lfd);return 0; }3.3 客户端 #include stdio.h #include unistd.h #include arpa/inet.h #include stdlib.h #include string.h #include netinet/in.h// 服务器的ip和端口 #define SERV_IP 127.0.0.1 #define SERV_PORT 6666int main() {int cfd; // 用于写入数据传输给服务端的socket的文件描述符cfd socket(AF_INET, SOCK_STREAM, 0);// bind() 可以不调用bind() linux会隐式地绑定struct sockaddr_in serv_addr; // 因为要连接服务端这里的sockadd_in是用于指定服务端的ip和端口bzero(serv_addr, sizeof(serv_addr));serv_addr.sin_family AF_INET;serv_addr.sin_port htons(SERV_PORT);inet_pton(AF_INET, SERV_IP, serv_addr.sin_addr.s_addr); // 调用ip转换函数把字符串ip转化为网络字节序connect(cfd, (struct sockaddr*)serv_addr, sizeof(serv_addr));while(1) {// 从终端读取内容char buf[BUFSIZ];fgets(buf, sizeof(buf), stdin); // 读一行// 写入到cfd中传输给服务端write(cfd, buf, strlen(buf)); // 注意不要写成sizeof(buf)sizeof是在内存中所占的大小strlen是到第一个\0位止。// read在读socket时默认时阻塞的阻塞等待服务端传输数据int len;len read(cfd, buf, sizeof(buf));printf(%s, buf);}close(cfd);return 0; }以上代码为突出主体没有写错误判断与错误提示。带错误提示代码如下 #include stdio.h #include unistd.h #include arpa/inet.h #include stdlib.h #include string.h #include netinet/in.h// 服务器的ip和端口 #define SERV_IP 127.0.0.1 #define SERV_PORT 6666int main() {int ret; // 用于错误检测int cfd; // 用于写入数据传输给服务端的socket的文件描述符cfd socket(AF_INET, SOCK_STREAM, 0);if(cfd -1) {perror(socket error);exit(1);}// bind() 可以不调用bind() linux会隐式地绑定struct sockaddr_in serv_addr; // 因为要连接服务端这里的sockadd_in是用于指定服务端的ip和端口bzero(serv_addr, sizeof(serv_addr));serv_addr.sin_family AF_INET;serv_addr.sin_port htons(SERV_PORT);inet_pton(AF_INET, SERV_IP, serv_addr.sin_addr.s_addr); // 调用ip转换函数把字符串ip转化为网络字节序ret connect(cfd, (struct sockaddr*)serv_addr, sizeof(serv_addr));if(ret -1) {perror(connect error);exit(1);}// 从终端读取内容while(1) {char buf[BUFSIZ];fgets(buf, sizeof(buf), stdin); // 读一行// 写入到cfd中传输给服务端ret write(cfd, buf, strlen(buf)); // 注意不要写成sizeof(buf)sizeof是在内存中所占的大小strlen是到第一个\0位止。if(ret -1) {perror(write error);exit(1);}// read在读socket时默认时阻塞的阻塞等待服务端传输数据int len;len read(cfd, buf, sizeof(buf));if(len -1) {perror(read error);exit(1);}printf(%s, buf);}close(cfd);return 0; }3.4 程序运行结果及注意事项 先启动server后启动client在client的终端输入小写字符后可见翻译成了大写 同时在server端输出了client的ip和端口号 程序有两个注意事项 先启动服务端再启动客户端。因为先启动客户端的话服务器来不及监听客户端就connect了会导致connect失败。 关闭时先关闭客户端再关闭服务端。如果先关闭服务端服务器程序处于TIME_WAIT状态程序中写死的6666端口号仍然被占用可以使用netstat -apn | grep 6666查看程序对6666端口占用情况
http://wiki.neutronadmin.com/news/88020/

相关文章:

  • 济南做网站最好的单位wordpress 邮件设置
  • 网站怎么加代码wordpress快速赚钱
  • pc版网站生成App学做网站论坛教学视频下载
  • 关于幼儿建设网站ppt网站流量优化
  • 建大型网站网站建设案例精英
  • 建设银行官方网站地址怎么制作公众号动图
  • 什么是html5网站备案网站地址
  • 专业网站建设服务商申请做网站 论坛版主
  • 网站设计 书籍一个虚拟主机空间挂两个网站
  • 来源门户网站源码做门户网站需要注册公司吗
  • 青岛做外贸网站建设鹿岛建设 网站
  • 5 网站建设进度表wordpress目录图片不显示
  • 住房及城乡建设部信息中心网站电子技术培训机构
  • 黑龙江省建设银行网站有手机版本wordpress
  • 做网站那个好亚马逊雨林的动物
  • 免费网站分析seo报告是坑吗酷家乐个人免费版官网
  • 百度怎么制作网站教程wordpress添加统计代码
  • 做复印机的模板网站电商加盟的网站建设
  • 网站后台编辑内容不显示金乡网站建设多少钱
  • 千城网站建设一般的电脑培训班要多少钱
  • 做娱乐网站做招聘网站怎么设计框架
  • 网站建设服务器怎么设置济南建设银行
  • 企业网站优化推广怎么做专业的句容网站建设
  • 外贸常用的网站公共资源交易中心忙吗
  • 哪些网站可以做一些任务挣钱响应式全屏网站模板
  • 网站改版收费濮阳的网站建设
  • 山西品牌网站建设88个seo网站优化基础知识点
  • 这样建立网站wordpress插件随机文章
  • 怎样创建公司网站dw网站的站点建设
  • 网站服务建设网络应用软件开发