做网站的开发语言,马云做网站最开始怎么盈利的,建立网站建站程序,稷山网站制作#xff08;4#xff09;本实验代码的蓝本#xff0c;是伊圣雨老师里的课本里的代码#xff0c;略加改动而来的。 以下是 服务器端的代码#xff1a; 每当收到客户端的报文时#xff0c;就测试一下对应的 epoll 事件里的事件标志#xff0c;不读取报文内容#xff0c;…4本实验代码的蓝本是伊圣雨老师里的课本里的代码略加改动而来的。 以下是 服务器端的代码 每当收到客户端的报文时就测试一下对应的 epoll 事件里的事件标志不读取报文内容所以设置为 ET 边缘触发模式。 对应的代码版本
#include stdio.h
#include stdlib.h
#include string.h
#include unistd.h
#include arpa/inet.h
#include sys/socket.h
#include sys/epoll.h
#include fcntl.h //增加这俩头文件
#include errno.h#define EPOLL_SIZE 50int main(int argc,char * argv[])
{ //验证 EPOLLHUP 等标志的服务器端, argc 2int serv_sock, clnt_sock, str_len, i, epfd, event_cnt;struct sockaddr_in serv_adr, clnt_adr;socklen_t adr_sz; struct epoll_event event, * ep_events;if(argc ! 2) { printf(参数不是2个\n);exit(1); }serv_sock socket(PF_INET,SOCK_STREAM,0);printf(创建了监听套接字,描述符为: %d\n,serv_sock);memset(serv_adr,0,sizeof(serv_adr));serv_adr.sin_family AF_INET; // 协议serv_adr.sin_addr.s_addr htonl(INADDR_ANY);//IP地址serv_adr.sin_port htons(atoi(argv[1])); //端口号bind( serv_sock,(struct sockaddr *)serv_adr, sizeof(serv_adr) ) ;listen(serv_sock,5);epfd epoll_create(EPOLL_SIZE); // EPOLL_SIZE 50event.events EPOLLIN; // 监听套接字仍为水平触发模式event.data.fd serv_sock;epoll_ctl(epfd, EPOLL_CTL_ADD, serv_sock, event);ep_events malloc(sizeof(struct epoll_event) * EPOLL_SIZE);while (1) // 此循环在正常情况下是不会退出的。{ event_cnt epoll_wait(epfd, ep_events, EPOLL_SIZE, -1); if(-1 event_cnt) { break; } // 出错则结束循环进程退出 puts(从 epoll_wait() 返回了);//统计epoll_wait()的返回次数for(i 0 ; i event_cnt ; i) //依次处理所有发生了事件的套接字{ if(ep_events[i].data.fd serv_sock)//监听套接字{ adr_sz sizeof(clnt_adr);clnt_sock accept( serv_sock,(struct sockaddr *)clnt_adr,adr_sz );event.events EPOLLIN | EPOLLHUP |EPOLLRDHUP | EPOLLET ;// 通信套接字用边缘触发是因为不准备读取报文event.data.fd clnt_sock; epoll_ctl(epfd, EPOLL_CTL_ADD, clnt_sock, event); printf(创建了通信套接字 id: %d\n, clnt_sock);} else { // 依次测试通讯套接字上有事件时具有的 epoll标志。uint32_t revents ep_events[i].events; int fd ep_events[i].data.fd;if( revents EPOLLIN ) printf(通信套接字 %d 上有 EPOLLIN 事件\n, fd);if( revents EPOLLHUP ) printf(通信套接字 %d 上有 EPOLLHUP 事件\n, fd);if( revents EPOLLRDHUP ) printf(通信套接字 %d 上有 EPOLLRDHUP 事件\n, fd);}} // for(...) } // while(...)return 0;
}5 接着给出客户端的版本这是一个 linux 版本的客户端很简单的小程序 记录其源代码版本
#include stdio.h
#include stdlib.h
#include string.h
#include unistd.h
#include arpa/inet.h
#include sys/socket.hint main(int argc,char * argv[])
{ // 回声客户端三个参数argc 3int sock, str_len; struct sockaddr_in serv_adr;if(argc ! 3) { printf(参数不是3个\n);exit(1); }sock socket(PF_INET,SOCK_STREAM,0);memset(serv_adr,0,sizeof(serv_adr));serv_adr.sin_family AF_INET;// serv_adr.sin_addr.s_addr inet_addr(argv[1]);// inet_addr() 的语义不明不好// 处理文本地址只需使用 inet_pton() 与 inet_ntop() 即可。// int inet_pton(int af, const char *src, void *dst);inet_pton(AF_INET, argv[1], serv_adr.sin_addr.s_addr);serv_adr.sin_port htons(atoi(argv[2]));if(connect(sock, (struct sockaddr *)serv_adr, sizeof(serv_adr)) ! -1)puts(客户端套接字连接至服务器成功\n);sleep(60); // 延迟 60s 以观察实验结果close(sock); // 此行可注释以验证 四次握手与 RST 报文的出现时机exit(0);
}6后来实验中发现客户端采用 linux 版本会导致 wireshark 无法抓包只好再编写 windows 版本的客户端源代码如下 代码版
#include stdio.h
#include stdlib.h
#include winsock2.h#pragma warning(disable : 4996) // 禁用关于 inet_addr 的过时警告int main()
{WSADATA m_wsadata; // 在 windows平台使用 socket前须做一下初始化,WSAStartup(0x0202, m_wsadata); // 最后用 WSACleanup() 释放库。SOCKET sClient socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);SOCKADDR_IN server_in;memset(server_in, 0, sizeof(SOCKADDR_IN)); //连接服务器server_in.sin_family AF_INET;server_in.sin_port htons(9000); // 连接至 80 端口server_in.sin_addr.s_addr inet_addr(192.168.1.126);connect(sClient, (struct sockaddr*)server_in, sizeof(SOCKADDR_IN));for (int i 0; i 1000000000; i); // 延时一下closesocket(sClient); // 关闭套接字的函数WSACleanup(); // 用这个函数关闭库return 0;
}使用 windows 的套接字还要设置一下 vs2019 要不然上面的代码会找不到外部函数。 以及 7 以下给出实验结果配合 wireshark 抓包 8
谢谢