socket 编程中,memcpy()的问题。

望大神指教。
定义了个结构体:

 struct USERDATA 
{
     char name[30];
     char passwd[30];
}
memcpy(userdata.name,"kakarot",sizeof("kakarot"));
memcpy(userdata.passwd,"123",sizeof("134"));
send() 之后;
char buffer[BUFSIZ] = "0";
recv(clntSock,buffer,BUFSIZ -1,0);
memcpy(&userdata,buffer,strlen(buffer));

可是为什么收的,只收到了name,而passwd为空

2个回答

memcpy(&userdata,buffer,strlen(buffer));//strlen改为 sizeof(struct USERDATA)

k876537
_yirol 回复linux_liyi: strlen() 遇见了结束标志所以长度不够。 值COPY 了,第一个。
4 年多之前 回复
q3733353520
我用双手-成就你的梦想 回复_yirol: 还有memcpy第3个参数是干什么的
4 年多之前 回复
q3733353520
我用双手-成就你的梦想 回复_yirol: 去查strlen和sizeof的功能
4 年多之前 回复
k876537
_yirol 为什么返回的接收长度都是60,而你这个可以,strlen() 却不可以?
4 年多之前 回复

"123",sizeof("134"),是不是这块问题,改成sizeof("123"),
或者你把源代码发下我调试看看

k876537
_yirol 谢谢,已经解决啦。
4 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
关于socket编程在java与c下的传输问题
最近在做一个项目,使用c写的客户端,用java写的服务器,客户端传输结构体,采用函数memcpy转换为字符串传输,那么在服务器端应该如何接受并解析??目前为止本人一直接受到的都是乱码
linux 下socket编程,客户端连接服务器失败
最近因为课程需要学习socket网络编程,运行的时候客户端无法与服务器建立连接,请原谅菜鸟没有积分,希望各位大佬给点帮助,解决下问题 这个是运行报错的截图 ![图片说明](https://img-ask.csdn.net/upload/201910/26/1572069361_597125.png) 以下是按照课本上编写的代码 客户端client.c ``` #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #define PROTOPORT 5188 extern int errno; char localhost[] = "localhost"; int main(int argc, char* argv[]) { struct hostent *ptrh; struct sockaddr_in servaddr; int sockfd; int port; char* host; int n; char buf[1000]; memset((char*)&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; if(argc > 2){ port = atoi(argv[2]); }else{ port = PROTOPORT; } if(port > 0){ servaddr.sin_port = htons((uint16_t)port); }else{ fprintf(stderr, " bad port number %s\n", argv[2]); exit(1); } if(argc > 1){ host = argv[1]; }else{ host = localhost; } ptrh = gethostbyname(host); if((char*)ptrh == NULL){ fprintf(stderr, " invalid host: %s\n", host); exit(1); } memcpy(&servaddr.sin_addr, ptrh->h_addr_list[0], ptrh->h_length); sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd > 0){ fprintf(stderr, " socket creation failed\n"); exit(1); } //请求连接到服务器 if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr))){ fprintf(stderr, "connect failed\n"); exit(1); } //从服务器读取数据,显示到用户屏幕上 n = recv(sockfd, buf, sizeof(buf), 0); while(n > 0){ write(1, buf, n); n = recv(sockfd, buf, sizeof(buf), 0); } //关闭连接 close(sockfd); //退出 exit(0); return 0; } ``` 服务器端server.c ``` #include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <string.h> #include <netinet/in.h> #include <netdb.h> #include <stdlib.h> #include <unistd.h> #define PROTOPORT 5188 #define QLEN 6 int visits = 0; int main(int argc, char * argv[]) { struct sockaddr_in servaddr; //存放服务器网络地址结构 struct sockaddr_in clientaddr; //存放客户机网络地址结构 int listenfd; int clientfd; int port; int alen; char buf[1000]; memset((char*)& servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = INADDR_ANY; if(argc >1){ port = atoi(argv[1]); }else{ port = PROTOPORT; } if(port > 0){ servaddr.sin_port = htons((uint16_t)port); }else{ fprintf(stderr, " bad port nuber %s\n", argv[1]); exit(1); } listenfd = socket(AF_INET, SOCK_STREAM, 0); if(listenfd < 0){ fprintf(stderr, "socket creation failed\n"); exit(1); } if(bind(listenfd, (struct sockaddr*) & servaddr, sizeof(servaddr)) < 0){ fprintf(stderr, " bind failed\n"); exit(1); } if(listen(listenfd, QLEN) < 0){ fprintf(stderr, "listen filed\n"); exit(0); } while(1) { alen = sizeof(clientaddr); if((clientfd = accept(listenfd, (struct sockaddr*) & clientaddr, (socklen_t*)&alen)) < 0){ fprintf(stderr, "accept failed\n"); exit(1); } visits++; sprintf(buf, "this server has been contacted %d time \n", visits); send(clientfd, buf, strlen(buf), 0); close(clientfd); } return 0; } ```
linux下socket编程 select只监测读事件, 为什么还会出现读阻塞
我用select监测读时间,但是read出现了阻塞 maxfd = iListenFdIP; maxi = -1; for(i=0 ; i<CONNCT_NUM_MAX; ++i) { client[i][0] = -1; }//for FD_ZERO(&allset); FD_SET(iListenFdIP , &allset); i = 0; while(1){ rset = allset; nready = select(maxfd+1 , &rset , NULL , NULL , NULL); // DEBUG(LOG_DEBUG,"nread:%d\n",nready); if(FD_ISSET(iListenFdIP , &rset)) { /*接收客户端的请求*/ clilen = sizeof(cliaddr); // DEBUG(LOG_DEBUG,"\naccpet connection~\n"); if((connfd = accept( iListenFdIP, (struct sockaddr *)&cliaddr , &clilen)) < 0) { DEBUG(LOG_ERROR,"accept error.\n"); continue; }//if DEBUG(LOG_DEBUG,"accpet a new client: %s:%d\n", inet_ntoa(cliaddr.sin_addr) , cliaddr.sin_port); /*将客户链接套接字描述符添加到数组*/ for(i=0 ; i<CONNCT_NUM_MAX ; ++i) { if(client[i][0] < 0) { client[i][0] = connfd; client[i][1] = cliaddr.sin_port; break; }//if }//for if(CONNCT_NUM_MAX == i) { DEBUG(LOG_ERROR,"too many connection.\n"); }//if else { FD_SET(connfd , &allset); if(connfd > maxfd) maxfd = connfd; if(i > maxi) maxi = i; } if(--nready < 0) continue; }//if // DEBUG(LOG_DEBUG,"maxi:%d\n",maxi); for(i=0; i<=maxi ; ++i) { memset(caBuff,0x0,sizeof(caBuff)); memset(sndBuff,0x0,sizeof(sndBuff)); memset(caSplitBuff,0x0,sizeof(caSplitBuff)); if((sockfd = client[i][0]) < 0) continue; if(FD_ISSET(sockfd , &rset)) { /*处理客户请求*/ //DEBUG(LOG_DEBUG,"\nreading the socket~~~ \n"); if((n = read(sockfd , caBuff , sizeof(caBuff))) <= 0) { DEBUG(LOG_DEBUG,"client[%d] is close\n",i); close(sockfd); FD_CLR(sockfd , &allset); client[i][0] = -1; }//if else{ char* cpPosNow = caBuff; if ( NULL == (cpPos = strchr(cpPosNow, '\n'))){ DEBUG(LOG_ERROR,"data:%s can't find '\n' \n",cpPosNow); continue; } iPkgLen = cpPos - cpPosNow; memcpy(caSplitBuff, cpPosNow, iPkgLen); inet_aton(caSplitBuff,&addr.sin_addr); memset(caSplitBuff,0x0,sizeof(caSplitBuff)); memcpy(&tmpIP,&addr.sin_addr,4); //tmpIP = htonl(tmpIP); memcpy(caSplitBuff,&tmpIP,4); if(NULL == (pIpMapHashNode = ipmap_hash_table_lookup((const unsigned char *)caSplitBuff))){ res = send(sockfd, "IPOFFLINE\n",strlen("IPOFFLINE\n") , 0); if(res < 0){ close(sockfd); FD_CLR(sockfd , &allset); client[i][0] = -1; DEBUG(LOG_DEBUG,"Send ERROR:Client is close,ErrorNum = %d, ErrorMsg = %s\n", errno, strerror(errno)); } } else{ DEBUG(LOG_DEBUG,"recv IPV4:%d.%d.%d.%d username:%s dstprot:%d\n", caSplitBuff[0],caSplitBuff[1],caSplitBuff[2],caSplitBuff[3],pIpMapHashNode->UserName,client[i][1]); memcpy(sndBuff, pIpMapHashNode->UserName, strlen(pIpMapHashNode->UserName)); strcat(sndBuff,"\n"); res = send(sockfd, sndBuff, strlen(pIpMapHashNode->UserName)+1, 0); if(res <= 0){ close(sockfd); FD_CLR(sockfd , &allset); client[i][0] = -1; DEBUG(LOG_DEBUG,"ERROR:Send Client is close,ErrorNum = %d, ErrorMsg = %s\n", errno, strerror(errno)); } } } if(--nready <= 0) break; } } } close(iListenFdIP); return;
请问如何用linux套接字编程来发挥万兆网卡的性能?
双线程,一个生产数据放入kfifo,一个从kfifo取出数据,通过套接字发送。最终测试出来速度只能达到400MB/S。(kfifo出队64KB数据要100us) 之后我将生产者做了更改,让它只更新队首的in指针,不做数据拷贝,此时速度能达到1000MB/S。(kfifo出队64KB数据只要10us) 我怀疑是生产者生产数据写入队列时,导致消费者所在的cpu cache失效,然后cache未命中导致速度骤降。但是不知道怎么解决这个问题。 在网上搜索答案,但是没有找到类似情况。看到有一个和我问题应该比较类似的,但是没有找到解决方法。 《请问为何tcp send第一次时很慢, 第二次时很快呢?》 https://www.oschina.net/question/2897213_2193602 ```c #include "szg_common.h" #include "szg_kfifo.h" #include "szg_socket.h" /**kfifo * 队列是将linux内核中的kfifo移到了这里来用,用malloc来替代内核中的kmalloc * 此代码(发送端)运行在NXP T4240上,系统linux,万兆网卡。 * 接收端软件运行在PC上,系统windows10,万兆网卡。 * * 1.正常出入队,kfifo总大小64M 元素大小256bytes 期望出队和期望入队都是256个元素 * 速度400MB/S 出队64k要100us send要50us * 2.注释掉kfifoin中的两行memcpy(szgKfifoCopyIn中的),让其只更新队首in指针 * 速度1000MB/S 出队64k要10us send要50us * * */ #define KFIFO_SEND_SIZE 0x10000 //64k #define FIFO_IN 0x100 //每次入队时期望入队的元素个数:256个(即256*256 = 64k) #define FIFO_OUT 0x100 //每次出队时期望出队的元素个数:256个(即256*256 = 64k) #define FIFO_E_SIZE 0x100 //元素大小:256byte #define FIFO_SIZE 0x4000000 //总大小:64Mbyte (256*256*1024个) kfifo testkFifo; void *szgTestKfifoThread(void *param) { UINT32 ret; char data_buf[KFIFO_SEND_SIZE] = {0}; while(TRUE) { ret = szgKfifoIn(&testkFifo,data_buf,FIFO_IN); if(ret == 0) { pthread_yield(); //usleep(2); } } } int kfifo_test(void) { INT32 listenFd; INT32 connectFd; INT32 ret; UINT32 clientIp; pthread_t threadId; pthread_attr_t attr; struct timeval start,end; char send_buf[KFIFO_SEND_SIZE]; memset(send_buf,1,KFIFO_SEND_SIZE); signal(SIGPIPE,SIG_IGN); /** * 初始化kfifo * 总大小 64M * 元素大小 256byes * 元素个数 256*1024个 * 出队,入队都是期望256个元素,不到256个有多少出多少,实际个数作为返回值返回 */ ret = szgKfifoAlloc(&testFifo,FIFO_SIZE/FIFO_E_SIZE,FIFO_E_SIZE); CHECK_EXIT(ret == ERROR, "fifo init err!"); /*创建线程,线程分离*/ pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); if (0 != pthread_create(&threadId,&attr, (void *)szgTestKfifoThread,NULL)) { SZG_LOG(SZG_LOG_ERR,"Create Thread data_filter_thread Fail \n"); return ERROR; } /*服务器初始化 端口6101 发送缓存2M 接收缓存1M(2M/2)*/ listenFd = szgSockInit(NULL,6101,0x200000); CHECK_EXIT(listenFd < 0, "socket error"); while(TRUE) { printf("wait connect\n"); /*客户端ip通过&clientIp返回(其实下面没用到)*/ connectFd = szgSockAccept(listenFd,&clientIp); if (connectFd < 0) { SZG_LOG(SZG_LOG_ERR,"server Accept Failed!/n"); return 0; } while(TRUE) { //gettimeofday(&start,NULL); /*出队 256*256 */ ret = szgKfifoOut(&testkFifo,send_buf,FIFO_OUT); if(ret == 0)//没有数据 { pthread_yield(); continue; //usleep(2); } //gettimeofday(&end,NULL); //printf("kfifo time %lu us \n",(1000000*(end.tv_sec-start.tv_sec) + (end.tv_usec-start.tv_usec))); /*发送64k*/ //gettimeofday(&start,NULL); ret = szgSendData(connectFd,send_buf,ret*FIFO_E_SIZE); if(ret == ERROR) { SZG_LOG(SZG_LOG_ERR,"szgSendData data error\n"); break; } //gettimeofday(&end,NULL); //printf("send time %lu us \n",(1000000*(end.tv_sec-start.tv_sec) + (end.tv_usec-start.tv_usec))); } } return 0; } ```
socket传输文件时遇到的问题!
先给出代码。 客户端: SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0); 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(4444); HANDLE fp =CreateFile(L"E:\\aTest.txt",GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); DWORD fileLen =GetFileSize(fp, &fileLen); cout << "你选择的文件大小为:" << fileLen << endl; connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); char * buffer = new char[fileLen]; DWORD bufferLen = 0; ReadFile(fp, buffer, fileLen, &bufferLen, NULL); bool isFirst = true; int sendLen = 0; int sentLen = 0; char sendBuffer[200]; int leftLen = fileLen; while (true) { if (isFirst) { sendLen = send(sockClient, "Test", 1, 0); isFirst = false; if (sendLen < 0) { cout << "第一帧发送失败,程序结束." << endl; break; } Sleep(1000); continue; } if ((leftLen <= 0) || (sentLen >= fileLen)) break; if (leftLen >= 200) { memcpy(sendBuffer, buffer + sentLen, 200); sendLen = send(sockClient, sendBuffer, 200, 0); if (sendLen < 0) { cout << "帧发送失败,程序结束." << endl; break; } } else { memcpy(sendBuffer, buffer + sentLen, leftLen); sendLen = send(sockClient, sendBuffer, leftLen, 0); if (sendLen < 0) { cout << "帧发送失败,程序结束." << endl; break; } Sleep(1000); send(sockClient, "#", 1, 0); } sentLen += sendLen; leftLen = fileLen - sentLen; cout << "已经发送" << sentLen << endl; } if (sentLen == fileLen) cout << "文件发送成功." << endl; else cout << "文件发送失败." << endl; closesocket(sockClient); WSACleanup(); delete[] buffer; } 服务器端: SOCKET socksrv = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrsrv; addrsrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); addrsrv.sin_family = AF_INET; addrsrv.sin_port = htons(4444); bind(socksrv, (sockaddr*)&addrsrv, sizeof(SOCKADDR)); listen(socksrv, 5); SOCKADDR_IN addrclient; int len = sizeof(SOCKADDR); int recvLen = 0; int recvedLen = 0; DWORD writeLen; int fileLen = 0; char* buffer; char recvBuffer[200]; while (1) { SOCKET sockconn = accept(socksrv, (SOCKADDR*)&addrclient, &len); buffer = new char[1024 * 1024 * 10]; recvLen = recv(sockconn, recvBuffer, 200, 0); if (recvBuffer[0] == 'test') { printf("开始接收文件\n"); memset(recvBuffer, 0, 200); } while (true) { recvLen = recv(sockconn, recvBuffer, 200, 0); if ((recvLen == 1) && (recvBuffer[0] == '#')) break; memcpy(buffer + recvedLen, recvBuffer, recvLen); recvedLen += recvLen; printf("接收:%d\n", recvLen); printf("已经接收%i字节数据\n", recvedLen); } HANDLE fp = CreateFile(L"C://Users\apple\Desktop", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(fp, buffer, recvedLen, &writeLen, NULL); printf("写入文件长度:%u\n", writeLen); delete[] buffer; WSACleanup(); } } 代码有点乱,还有许多要改的地方,但是大体框架是这样。 运行的时候,客户端能够成功发送文件,服务器端也能正确显示接受的文件大小,然后写入文件却是0,然后就报错,不知道是为什么?
c++ SYN 网络编程遇到问题 小白求教
以下是代码,运行无错误,但是用wireshark 抓不到发出的SYN包,求高手解释原因。。 ``` #include <stdlib.h> #include <stdio.h> #include <winsock2.h> //加入WinSock的头文件 #include <WS2TCPIP.h> //设置IP_HDRINCL选中需要 #include <time.h> #include <iostream> using namespace std; #pragma comment(lib,"Ws2_32.lib") //加入库函数 typedef struct //定义IP首部 { unsigned char h_verlen; //4位首部长度,4位IP版本号 unsigned char tos; //8位服务类型TOS unsigned short total_len; //16位总长度(字节) unsigned short ident; //16位标识 unsigned short frag_and_flags; //3位标志位 unsigned char ttl; //8位生存时间 TTL unsigned char proto; //8位协议 (TCP, UDP 或其他) unsigned short checksum; //16位IP首部校验和 unsigned int sourceIP; //32位源IP地址 unsigned int destIP; //32位目的IP地址 }IPHEADER; typedef struct //定义TCP首部 { USHORT th_sport; //16位源端口 USHORT th_dport; //16位目的端口 unsigned int th_seq; //32位序列号 unsigned int th_ack; //32位确认号 unsigned char th_lenres; //4位首部长度/6位保留字 unsigned char th_flag; //6位标志位 USHORT th_win; //16位窗口大小 USHORT th_sum; //16位校验和 USHORT th_urp; //16位紧急数据偏移量 }TCPHEADER; typedef struct //定义TCP伪首部 { unsigned long saddr; //源地址 unsigned long daddr; //目的地址 char mbz; char ptcl; //协议类型 unsigned short tcpl; //TCP长度 }PSDHEADER; //计算校验和函数 USHORT checksum(USHORT *buffer, int size) { unsigned long cksum=0; while(size >1) { cksum+=*buffer++; size -=sizeof(USHORT); } if(size ) { cksum += *(UCHAR*)buffer; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (USHORT)(~cksum); } //void packet_input(); int main() { WSADATA WSAData; if ( WSAStartup(MAKEWORD(2,2), &WSAData)!=0 ) { printf("InitWSAStartup Error!\n"); return 0; } char ip[20]="192.168.3.1"; u_short port; SOCKET sock; SOCKADDR_IN addr_in; IPHEADER ipHeader; TCPHEADER tcpHeader; PSDHEADER psdHeader; char szSendBuf[60]={0}; int rect,nTimeOver; if ((sock = WSASocket(2,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET) { printf("sock err!"); return 0; } //设置IP_HDRINCL选项,声明自己填充IP头部 BOOL blnFlag=TRUE; if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&blnFlag, sizeof(blnFlag))==INVALID_SOCKET) { printf("opt err!"); return 0; } nTimeOver=1000; if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver))==SOCKET_ERROR) { printf("time err!"); return 0; } ////////////////////////////////////////////////////////////////////////// port=80; addr_in.sin_family=AF_INET; addr_in.sin_port=htons(port); //目标端口 addr_in.sin_addr.S_un.S_addr=inet_addr(ip); //目标IP while(true) { printf("."); for(int counter=0;counter<10240;counter++) { //填充IP首部 ipHeader.h_verlen=(4<<4 | sizeof(ipHeader)/sizeof(unsigned long)); //高四位IP版本号,低四位首部长度 ipHeader.tos=0; ipHeader.total_len=htons(sizeof(ipHeader)+sizeof(tcpHeader)); //16位总长度 ipHeader.ident=htons(1); ipHeader.frag_and_flags=0; ipHeader.ttl=128; //8位生存时间TTL ipHeader.proto=IPPROTO_TCP; ipHeader.checksum=0; ipHeader.sourceIP=inet_addr("192.168.3.70"); ipHeader.destIP=inet_addr(ip); //填充TCP首部 tcpHeader.th_dport=htons(port); //源端口号 tcpHeader.th_sport=htons(2337); //目的端口号 tcpHeader.th_seq=0; //SYN序列号 tcpHeader.th_ack=0; //ACK序列号置0 tcpHeader.th_lenres=(sizeof(tcpHeader)/4<<4|0); //tcp长度和保留位 tcpHeader.th_flag=2; //修改这里来实现不同的标志位探测,2是SYN,1是FIN,16是ACK探测 等等 tcpHeader.th_win=htons(512); tcpHeader.th_urp=0; tcpHeader.th_sum=0; psdHeader.saddr=ipHeader.sourceIP; psdHeader.daddr=ipHeader.destIP; psdHeader.mbz=0; psdHeader.ptcl=IPPROTO_TCP; psdHeader.tcpl=htons(sizeof(tcpHeader)); //计算校验和 memcpy(szSendBuf, &psdHeader, sizeof(psdHeader)); memcpy(szSendBuf+sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader)); tcpHeader.th_sum=checksum((USHORT *)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader)); memcpy(szSendBuf, &ipHeader, sizeof(ipHeader)); memcpy(szSendBuf+sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader)); ipHeader.checksum=checksum((USHORT *)szSendBuf, sizeof(ipHeader)); memcpy(szSendBuf, &ipHeader, sizeof(ipHeader)); rect=sendto(sock, szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader),0, (SOCKADDR*)&addr_in, sizeof(SOCKADDR)); if (rect==SOCKET_ERROR) { printf("Send err!"); return 0; } else { printf("Ip Ident:%d\n",ntohs(ipHeader.ident)); struct in_addr a; a.s_addr=ipHeader.sourceIP; printf("Ip saddr:%s\n",inet_ntoa(a)); //printf("Ip daddr:%s\n",ipHeader.destIP); } } } // end while closesocket(sock); return 0; } ```
原始套接字实现SYN扫描,但用wireshark时始终没有发现发出去的包
#include<iostream> #include<winsock2.h> #include<string.h> #include<mstcpip.h> #include<CommCtrl.h> #include "WS2TCPIP.H" #pragma comment(lib,"Ws2_32.lib") using namespace std; //SOCKADDR_IN target, source; //sockaddr_in target, source; //int sock; typedef struct _iphdr { unsigned char h_verlen; //4位首部长度+4位IP版本号 unsigned char tos; //8位服务类型TOS unsigned short total_len; //16位总长度(字节) unsigned short ident; //16位标识 unsigned short frag_and_flags; //3位标志位 unsigned char ttl; //8位生存时间TTL unsigned char proto; //8位协议(TCP、UDP或其他协议) unsigned short checksum; //16位IP首部校验和 unsigned int sourceIP; //32位源IP地址 unsigned int destIP; //32位目的IP地址 }IPHEADER; //TCP伪首部的作用主要是进行校验和的计算 typedef struct psd_hdr //定义TCP伪首部 { unsigned long saddr; //源地址 unsigned long daddr; //目的地址 char mbz; char ptcl; //协议类型 unsigned short tcpl; //TCP长度 }PSDHEADER; typedef struct _tcphdr //定义TCP首部 { USHORT th_sport; //16位源端口 USHORT th_dport; //16位目的端口 unsigned int th_seq; //32位序列号 unsigned int th_ack; //32位确认号 unsigned char th_lenres; //4位首部长度/6位保留字 unsigned char th_flag; //6位标志位 USHORT th_win; //16位窗口大小 USHORT th_sum; //16位校验和 USHORT th_urp; //16位紧急数据偏移量 }TCPHEADER; #define FINISH 100 #define RUN 200 #define SIO_WSAIOW(IOC_VENDOR,l) #define SEQ 0x28376839 USHORT CheckSum(USHORT *buffer, int size) //CRC校验通用代码 { unsigned long cksum = 0; while (size > 1) { cksum += *buffer++; size -= sizeof(USHORT); } if (size) cksum += *(UCHAR*)buffer; cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >> 16); return (USHORT)(~cksum); } //************************IP解包****************** /* int DecodeIPHeader(char *recvbuf, int bytes) { IPHEADER *iphdr; TCPHEADER *tcphdr; unsigned short iphdrlen; iphdr = (IPHEADER *)recvbuf; iphdrlen = sizeof(unsigned long) * (iphdr->h_verlen & 0xf); iphdrlen = sizeof(IPHEADER); tcphdr = (TCPHEADER*)(recvbuf + iphdrlen); //是否来自目标IP if (iphdr->sourceIP != target.sin_addr.s_addr) { printf("不来自目标IP\n"); return 0; } //序列号是否正确 if (ntohl(tcphdr->th_ack) != (SEQ + 1)) { printf("序列号错误\n"); return 0; } //RST/ACK - 无服务 if (tcphdr->th_flag == 20) { printf("RST+ACK 无服务.\n"); return 1; } //SYN/ACK - 扫描到一个端口 if (tcphdr->th_flag == 18) { printf("%d\n", ntohs(tcphdr->th_sport)); return 2; } printf("未知\n"); return 1; } */ //////////////////////////////////////////////////////////////////////// void SynScan(string uIP, u_short uPortBegin, u_short uPortEnd) { int datasize; IPHEADER ipHeader;//IP包头 TCPHEADER tcpHeader;//TCP包头 PSDHEADER psdHeader;//伪TCP包头 //**********************扫描顺序*********************** for (u_short port = uPortBegin;port<uPortEnd;port++) //端口顺序 { //SOCKET sock = INVALID_SOCKET; //SOCKET sock; int sock; SOCKADDR_IN target, source; WSADATA data; WORD w = MAKEWORD(2, 2); WSAStartup(w, &data); if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == INVALID_SOCKET) { cout << "发送原始套接字Socket创建出错" << endl << GetLastError() << endl; return; } //**********************扫描顺序*********************** BOOL flag = true; if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag)) == SOCKET_ERROR) { cout << "套接字选项IP_HDRINCL出错!\n" << endl; return; } //SIO_RCVALL函数是可以读取所有IP数据包的必要设置 DWORD dwBufferLen[10]; DWORD dwBufferInLen = 1; DWORD dwBytesReturned = 0; WSAIoctl(sock, _WSAIOW(IOC_VENDOR, 1), &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen), &dwBytesReturned, NULL, NULL); setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&flag, sizeof(flag)); source.sin_family = AF_INET; source.sin_port = htons(53638); source.sin_addr.s_addr = inet_addr("10.15.57.28");//本机IP地址 if (bind(sock, (PSOCKADDR)&source, sizeof(source)) == SOCKET_ERROR) cout << "绑定本地IP接收出错。" << endl; target.sin_family = AF_INET; target.sin_addr.s_addr = inet_addr(uIP.c_str()); //对方IP target.sin_port = htons(port); //对方端口 cout << uIP.c_str() << endl; //分别自己填充IP头、TCP头、伪IP头,并计算其中的校验和 char SendBuf[1024] = { 0 }; //设置IP包头 ipHeader.h_verlen = (4 << 4 | sizeof(ipHeader) / sizeof(unsigned long)); ipHeader.tos = 0; ipHeader.total_len = htons(sizeof(ipHeader) + sizeof(tcpHeader)); ipHeader.ident = 1; ipHeader.frag_and_flags = 0; ipHeader.ttl = 128; ipHeader.proto = IPPROTO_TCP; ipHeader.checksum = 0; ipHeader.sourceIP = source.sin_addr.s_addr; ipHeader.destIP = target.sin_addr.s_addr; //设置TCP头 tcpHeader.th_sport = source.sin_port; //本地端口 tcpHeader.th_dport = target.sin_port; //目标端口 tcpHeader.th_seq = htonl(SEQ); tcpHeader.th_ack = 0; tcpHeader.th_lenres = (sizeof(tcpHeader) / 4 << 4 | 0); tcpHeader.th_flag = 2; //2为SYN,1为FIN,16为ACK tcpHeader.th_win = htons(16384); tcpHeader.th_urp = 0; tcpHeader.th_sum = 0; //伪TCP头 psdHeader.saddr = ipHeader.sourceIP; psdHeader.daddr = ipHeader.destIP; psdHeader.mbz = 0; psdHeader.ptcl = IPPROTO_TCP; psdHeader.tcpl = htons(sizeof(tcpHeader)); //计算校验和 memcpy(SendBuf, &psdHeader, sizeof(psdHeader)); memcpy(SendBuf + sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader)); tcpHeader.th_sum = CheckSum((USHORT *)SendBuf, sizeof(psdHeader) + sizeof(tcpHeader)); memcpy(SendBuf, &ipHeader, sizeof(ipHeader)); memcpy(SendBuf + sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader)); memset(SendBuf + sizeof(ipHeader) + sizeof(tcpHeader), 0, 4); ipHeader.checksum = CheckSum((USHORT*)SendBuf, sizeof(ipHeader) + sizeof(tcpHeader)); //复制IP包+TCP包,进行发送 memcpy(SendBuf, &ipHeader, sizeof(ipHeader)); if ((sendto(sock, SendBuf, sizeof(ipHeader) + sizeof(tcpHeader), 0, (struct sockaddr *)&target, sizeof(struct sockaddr))) < 0) { cout << "sendto error" << endl << GetLastError() << endl; } int buflen = sizeof(target); memset(RecvBuf, 0, sizeof(RecvBuf)); cout << "端口 " << port << endl; shutdown(sock, 2); closesocket(sock); WSACleanup(); } } int main() { string ip = "10.15.57.1"; SynScan(ip, 1, 500); system("pause"); return 0; } ``` ```
在中国程序员是青春饭吗?
今年,我也32了 ,为了不给大家误导,咨询了猎头、圈内好友,以及年过35岁的几位老程序员……舍了老脸去揭人家伤疤……希望能给大家以帮助,记得帮我点赞哦。 目录: 你以为的人生 一次又一次的伤害 猎头界的真相 如何应对互联网行业的「中年危机」 一、你以为的人生 刚入行时,拿着傲人的工资,想着好好干,以为我们的人生是这样的: 等真到了那一天,你会发现,你的人生很可能是这样的: ...
【JSON解析】浅谈JSONObject的使用
简介 在程序开发过程中,在参数传递,函数返回值等方面,越来越多的使用JSON。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,同时也易于机器解析和生成、易于理解、阅读和撰写,而且Json采用完全独立于语言的文本格式,这使得Json成为理想的数据交换语言。 JSON建构于两种结构: “名称/值”对的集合(A Collection of name/va...
《MySQL 性能优化》之理解 MySQL 体系结构
本文介绍 MySQL 的体系结构,包括物理结构、逻辑结构以及插件式存储引擎。
程序员请照顾好自己,周末病魔差点一套带走我。
程序员在一个周末的时间,得了重病,差点当场去世,还好及时挽救回来了。
一名大专同学的四个问题
【前言】   收到一封来信,赶上各种事情拖了几日,利用今天要放下工作的时机,做个回复。   2020年到了,就以这一封信,作为开年标志吧。 【正文】   您好,我是一名现在有很多困惑的大二学生。有一些问题想要向您请教。   先说一下我的基本情况,高考失利,不想复读,来到广州一所大专读计算机应用技术专业。学校是偏艺术类的,计算机专业没有实验室更不用说工作室了。而且学校的学风也不好。但我很想在计算机领...
复习一周,京东+百度一面,不小心都拿了Offer
京东和百度一面都问了啥,面试官百般刁难,可惜我全会。
Java 14 都快来了,为什么还有这么多人固守Java 8?
从Java 9开始,Java版本的发布就让人眼花缭乱了。每隔6个月,都会冒出一个新版本出来,Java 10 , Java 11, Java 12, Java 13, 到2020年3月份,...
达摩院十大科技趋势发布:2020 非同小可!
【CSDN编者按】1月2日,阿里巴巴发布《达摩院2020十大科技趋势》,十大科技趋势分别是:人工智能从感知智能向认知智能演进;计算存储一体化突破AI算力瓶颈;工业互联网的超融合;机器间大规模协作成为可能;模块化降低芯片设计门槛;规模化生产级区块链应用将走入大众;量子计算进入攻坚期;新材料推动半导体器件革新;保护数据隐私的AI技术将加速落地;云成为IT技术创新的中心 。 新的画卷,正在徐徐展开。...
轻松搭建基于 SpringBoot + Vue 的 Web 商城应用
首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。Fun: Fun 是一个用于支持 Serverless 应用部署的工具,能帮助您便捷地管理函数计算、API ...
讲真,这两个IDE插件,可以让你写出质量杠杠的代码
周末躺在床上看《拯救大兵瑞恩》 周末在闲逛的时候,发现了两个优秀的 IDE 插件,据说可以提高代码的质量,我就安装了一下,试了试以后发现,确实很不错,就推荐给大家。 01、Alibaba Java 代码规范插件 《阿里巴巴 Java 开发手册》,相信大家都不会感到陌生,其 IDEA 插件的下载次数据说达到了 80 万次,我今天又贡献了一次。嘿嘿。 该项目的插件地址: https://github....
Python+OpenCV实时图像处理
目录 1、导入库文件 2、设计GUI 3、调用摄像头 4、实时图像处理 4.1、阈值二值化 4.2、边缘检测 4.3、轮廓检测 4.4、高斯滤波 4.5、色彩转换 4.6、调节对比度 5、退出系统 初学OpenCV图像处理的小伙伴肯定对什么高斯函数、滤波处理、阈值二值化等特性非常头疼,这里给各位分享一个小项目,可通过摄像头实时动态查看各类图像处理的特点,也可对各位调参、测试...
2020年一线城市程序员工资大调查
人才需求 一线城市共发布岗位38115个,招聘120827人。 其中 beijing 22805 guangzhou 25081 shanghai 39614 shenzhen 33327 工资分布 2020年中国一线城市程序员的平均工资为16285元,工资中位数为14583元,其中95%的人的工资位于5000到20000元之间。 和往年数据比较: yea...
为什么猝死的都是程序员,基本上不见产品经理猝死呢?
相信大家时不时听到程序员猝死的消息,但是基本上听不到产品经理猝死的消息,这是为什么呢? 我们先百度搜一下:程序员猝死,出现将近700多万条搜索结果: 搜索一下:产品经理猝死,只有400万条的搜索结果,从搜索结果数量上来看,程序员猝死的搜索结果就比产品经理猝死的搜索结果高了一倍,而且从下图可以看到,首页里面的五条搜索结果,其实只有两条才是符合条件。 所以程序员猝死的概率真的比产品经理大,并不是错...
害怕面试被问HashMap?这一篇就搞定了!
声明:本文以jdk1.8为主! 搞定HashMap 作为一个Java从业者,面试的时候肯定会被问到过HashMap,因为对于HashMap来说,可以说是Java集合中的精髓了,如果你觉得自己对它掌握的还不够好,我想今天这篇文章会非常适合你,至少,看了今天这篇文章,以后不怕面试被问HashMap了 其实在我学习HashMap的过程中,我个人觉得HashMap还是挺复杂的,如果真的想把它搞得明明白...
毕业5年,我问遍了身边的大佬,总结了他们的学习方法
我问了身边10个大佬,总结了他们的学习方法,原来成功都是有迹可循的。
python爬取百部电影数据,我分析出了一个残酷的真相
2019年就这么匆匆过去了,就在前几天国家电影局发布了2019年中国电影市场数据,数据显示去年总票房为642.66亿元,同比增长5.4%;国产电影总票房411.75亿元,同比增长8.65%,市场占比 64.07%;城市院线观影人次17.27亿,同比增长0.64%。 看上去似乎是一片大好对不对?不过作为一名严谨求实的数据分析师,我从官方数据中看出了一点端倪:国产票房增幅都已经高达8.65%了,为什...
推荐10个堪称神器的学习网站
每天都会收到很多读者的私信,问我:“二哥,有什么推荐的学习网站吗?最近很浮躁,手头的一些网站都看烦了,想看看二哥这里有什么新鲜货。” 今天一早做了个恶梦,梦到被老板辞退了。虽然说在我们公司,只有我辞退老板的份,没有老板辞退我这一说,但是还是被吓得 4 点多都起来了。(主要是因为我掌握着公司所有的核心源码,哈哈哈) 既然 4 点多起来,就得好好利用起来。于是我就挑选了 10 个堪称神器的学习网站,推...
这些软件太强了,Windows必装!尤其程序员!
Windows可谓是大多数人的生产力工具,集娱乐办公于一体,虽然在程序员这个群体中都说苹果是信仰,但是大部分不都是从Windows过来的,而且现在依然有很多的程序员用Windows。 所以,今天我就把我私藏的Windows必装的软件分享给大家,如果有一个你没有用过甚至没有听过,那你就赚了????,这可都是提升你幸福感的高效率生产力工具哦! 走起!???? NO、1 ScreenToGif 屏幕,摄像头和白板...
阿里面试,面试官没想到一个ArrayList,我都能跟他扯半小时
我是真的没想到,面试官会这样问我ArrayList。
曾经优秀的人,怎么就突然不优秀了。
职场上有很多辛酸事,很多合伙人出局的故事,很多技术骨干被裁员的故事。说来模板都类似,曾经是名校毕业,曾经是优秀员工,曾经被领导表扬,曾经业绩突出,然而突然有一天,因为种种原因,被裁员了,...
大学四年因为知道了这32个网站,我成了别人眼中的大神!
依稀记得,毕业那天,我们导员发给我毕业证的时候对我说“你可是咱们系的风云人物啊”,哎呀,别提当时多开心啦????,嗯,我们导员是所有导员中最帅的一个,真的???? 不过,导员说的是实话,很多人都叫我大神的,为啥,因为我知道这32个网站啊,你说强不强????,这次是绝对的干货,看好啦,走起来! PS:每个网站都是学计算机混互联网必须知道的,真的牛杯,我就不过多介绍了,大家自行探索,觉得没用的,尽管留言吐槽吧???? 社...
良心推荐,我珍藏的一些Chrome插件
上次搬家的时候,发了一个朋友圈,附带的照片中不小心暴露了自己的 Chrome 浏览器插件之多,于是就有小伙伴评论说分享一下我觉得还不错的浏览器插件。 我下面就把我日常工作和学习中经常用到的一些 Chrome 浏览器插件分享给大家,随便一个都能提高你的“生活品质”和工作效率。 Markdown Here Markdown Here 可以让你更愉快的写邮件,由于支持 Markdown 直接转电子邮...
看完这篇HTTP,跟面试官扯皮就没问题了
我是一名程序员,我的主要编程语言是 Java,我更是一名 Web 开发人员,所以我必须要了解 HTTP,所以本篇文章就来带你从 HTTP 入门到进阶,看完让你有一种恍然大悟、醍醐灌顶的感觉。 最初在有网络之前,我们的电脑都是单机的,单机系统是孤立的,我还记得 05 年前那会儿家里有个电脑,想打电脑游戏还得两个人在一个电脑上玩儿,及其不方便。我就想为什么家里人不让上网,我的同学 xxx 家里有网,每...
史上最全的IDEA快捷键总结
现在Idea成了主流开发工具,这篇博客对其使用的快捷键做了总结,希望对大家的开发工作有所帮助。
阿里程序员写了一个新手都写不出的低级bug,被骂惨了。
这种新手都不会范的错,居然被一个工作好几年的小伙子写出来,差点被当场开除了。
谁是华为扫地僧?
是的,华为也有扫地僧!2020年2月11-12日,“养在深闺人不知”的华为2012实验室扫地僧们,将在华为开发者大会2020(Cloud)上,和大家见面。到时,你可以和扫地僧们,吃一个洋...
AI 没让人类失业,搞 AI 的人先失业了
最近和几个 AI 领域的大佬闲聊 根据他们讲的消息和段子 改编出下面这个故事 如有雷同 都是巧合 1. 老王创业失败,被限制高消费 “这里写我跑路的消息实在太夸张了。” 王葱葱哼笑一下,把消息分享给群里。 阿杰也看了消息,笑了笑。在座几位也都笑了。 王葱葱是个有名的人物,21岁那年以全额奖学金进入 KMU 攻读人工智能博士,累计发表论文 40 余篇,个人技术博客更是成为深度学习领域内风向标。 ...
2020年,冯唐49岁:我给20、30岁IT职场年轻人的建议
点击“技术领导力”关注∆每天早上8:30推送 作者|Mr.K 编辑| Emma 来源|技术领导力(ID:jishulingdaoli) 前天的推文《冯唐:职场人35岁以后,方法论比经验重要》,收到了不少读者的反馈,觉得挺受启发。其实,冯唐写了不少关于职场方面的文章,都挺不错的。可惜大家只记住了“春风十里不如你”、“如何避免成为油腻腻的中年人”等不那么正经的文章。 本文整理了冯...
作为一名大学生,如何在B站上快乐的学习?
B站是个宝,谁用谁知道???? 作为一名大学生,你必须掌握的一项能力就是自学能力,很多看起来很牛X的人,你可以了解下,人家私底下一定是花大量的时间自学的,你可能会说,我也想学习啊,可是嘞,该学习啥嘞,不怕告诉你,互联网时代,最不缺的就是学习资源,最宝贵的是啥? 你可能会说是时间,不,不是时间,而是你的注意力,懂了吧! 那么,你说学习资源多,我咋不知道,那今天我就告诉你一个你必须知道的学习的地方,人称...
那些年,我们信了课本里的那些鬼话
教材永远都是有错误的,从小学到大学,我们不断的学习了很多错误知识。 斑羚飞渡 在我们学习的很多小学课文里,有很多是错误文章,或者说是假课文。像《斑羚飞渡》: 随着镰刀头羊的那声吼叫,整个斑羚群迅速分成两拨,老年斑羚为一拨,年轻斑羚为一拨。 就在这时,我看见,从那拨老斑羚里走出一只公斑羚来。公斑羚朝那拨年轻斑羚示意性地咩了一声,一只半大的斑羚应声走了出来。一老一少走到伤心崖,后退了几步,突...
一个程序在计算机中是如何运行的?超级干货!!!
强烈声明:本文很干,请自备茶水!???? 开门见山,咱不说废话! 你有没有想过,你写的程序,是如何在计算机中运行的吗?比如我们搞Java的,肯定写过这段代码 public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } ...
【蘑菇街技术部年会】程序员与女神共舞,鼻血再次没止住。(文末内推)
蘑菇街技术部的年会,别开生面,一样全是美女。
那个在阿里养猪的工程师,5年了……
简介: 在阿里,走过1825天,没有趴下,依旧斗志满满,被称为“五年陈”。他们会被授予一枚戒指,过程就叫做“授戒仪式”。今天,咱们听听阿里的那些“五年陈”们的故事。 下一个五年,猪圈见! 我就是那个在养猪场里敲代码的工程师,一年多前我和20位工程师去了四川的猪场,出发前总架构师慷慨激昂的说:同学们,中国的养猪产业将因为我们而改变。但到了猪场,发现根本不是那么回事:要个WIFI,没有;...
为什么程序猿都不愿意去外包?
分享外包的组织架构,盈利模式,亲身经历,以及根据一些外包朋友的反馈,写了这篇文章 ,希望对正在找工作的老铁有所帮助
Java校招入职华为,半年后我跑路了
何来 我,一个双非本科弟弟,有幸在 19 届的秋招中得到前东家华为(以下简称 hw)的赏识,当时秋招签订就业协议,说是入了某 java bg,之后一系列组织架构调整原因等等让人无法理解的神操作,最终毕业前夕,被通知调往其他 bg 做嵌入式开发(纯 C 语言)。 由于已至于校招末尾,之前拿到的其他 offer 又无法再收回,一时感到无力回天,只得默默接受。 毕业后,直接入职开始了嵌入式苦旅,由于从未...
世界上有哪些代码量很少,但很牛逼很经典的算法或项目案例?
点击上方蓝字设为星标下面开始今天的学习~今天分享四个代码量很少,但很牛逼很经典的算法或项目案例。1、no code 项目地址:https://github.com/kelseyhight...
Python全栈 Linux基础之3.Linux常用命令
Linux对文件(包括目录)有很多常用命令,可以加快开发效率:ls是列出当前目录下的文件列表,选项有-a、-l、-h,还可以使用通配符;c功能是跳转目录,可以使用相对路径和绝对路径;mkdir命令创建一个新的目录,有-p选项,rm删除文件或目录,有-f、-r选项;cp用于复制文件,有-i、-r选项,tree命令可以将目录结构显示出来(树状显示),有-d选项,mv用来移动文件/目录,有-i选项;cat查看文件内容,more分屏显示文件内容,grep搜索内容;>、>>将执行结果重定向到一个文件;|用于管道输出。
​两年前不知如何编写代码的我,现在是一名人工智能工程师
全文共3526字,预计学习时长11分钟 图源:Unsplash 经常有小伙伴私信给小芯,我没有编程基础,不会写代码,如何进入AI行业呢?还能赶上AI浪潮吗? 任何时候努力都不算晚。 下面,小芯就给大家讲一个朋友的真实故事,希望能给那些处于迷茫与徘徊中的小伙伴们一丝启发。(下文以第一人称叙述) 图源:Unsplash 正如Elsa所说,职业转换是...
强烈推荐10本程序员必读的书
很遗憾,这个春节注定是刻骨铭心的,新型冠状病毒让每个人的神经都是紧绷的。那些处在武汉的白衣天使们,尤其值得我们的尊敬。而我们这些窝在家里的程序员,能不外出就不外出,就是对社会做出的最大的贡献。 有些读者私下问我,窝了几天,有点颓丧,能否推荐几本书在家里看看。我花了一天的时间,挑选了 10 本我最喜欢的书,你可以挑选感兴趣的来读一读。读书不仅可以平复恐惧的压力,还可以对未来充满希望,毕竟苦难终将会...
非典逼出了淘宝和京东,新冠病毒能够逼出什么?
loonggg读完需要5分钟速读仅需 2 分钟大家好,我是你们的校长。我知道大家在家里都憋坏了,大家可能相对于封闭在家里“坐月子”,更希望能够早日上班。今天我带着大家换个思路来聊一个问题...
牛逼!一行代码居然能解决这么多曾经困扰我半天的算法题
春节假期这么长,干啥最好?当然是折腾一些算法题了,下面给大家讲几道一行代码就能解决的算法题,当然,我相信这些算法题你都做过,不过就算做过,也是可以看一看滴,毕竟,你当初大概率不是一行代码解决的。 学会了一行代码解决,以后遇到面试官问起的话,就可以装逼了。 一、2 的幂次方 问题描述:判断一个整数 n 是否为 2 的幂次方 对于这道题,常规操作是不断这把这个数除以 2,然后判断是否有余数,直到 ...
立即提问