我有这个功能
void save_ad(int n,char arr[n])
{
int i=0;
int price=0;
char title[100];
printf("entered\n");
while(i<n)
{
if(strncmp((char*)&arr[i],"title=",sizeof("title="))==0)
{
int x=0;
while(arr[x]!='\r')
{
printf("%c\n",arr[x]);
}
printf("\n");
}
i++;
}
printf("\n");
}
Run Code Online (Sandbox Code Playgroud)
arr 是从另一个函数传递的,它包含 this
add?title=samsung&price=22000 HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Run Code Online (Sandbox Code Playgroud)
所以我喜欢提取这一行,add?title=samsung&price=22000 HTTP/1.1因为这就是函数save_ad。但问题是我无法理解为什么我无法通过arr像这样传递数组第 i 个索引的地址来进行比较
if(strncmp((char*)&arr[i],"title=",sizeof("title="))==0)
Run Code Online (Sandbox Code Playgroud)
在索引 4 处,单词title开始,但我无法使用strncmp函数来比较它。在索引 4 处,如果两个字符串相等,则返回 19,该值不是 0
这是我的调用函数
int process(int size,char buffer[size],char status)
{
int i=0;
int line_len=0;
char *line=malloc(sizeof(char) *150);
while(i<size)
{
if(strncmp((void *)&buffer[i],"style9.css",strlen("style9.css"))==0)
return 3;
if(strncmp((void *)&buffer[i],"GET / HTTP/1.1",14)==0)
{
while(buffer[i]!='\n')
{
line[line_len]=buffer[i];
line_len++;
i++;
}
//line[line_len]='\0';
//printf("%s\n",line);
memset(line,0,line_len);
line_len=0;
return 2;
}
if(strncmp((void*)&buffer[i],"add?",strlen("add?"))==0)
{
save_ad(size-i,(void*)&buffer[i]);
}
i++;
line_len++;
}
return 2;
}
Run Code Online (Sandbox Code Playgroud)
如果我arr在 save_ad 函数中 printf 或在 gdb 中查看,它仍然打印包含以下内容的 arr
add?title=samsung&price=22000 HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Run Code Online (Sandbox Code Playgroud)
这是完整的代码
// Server side C/C++ program to demonstrate Socket programming
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
//aaa
#define PORT 80
#define BUF_SIZE 20000
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
int min(int a, int b)
{
return a>b?b:a;
}
void save_ad(int n,char arr[n])
{
int i=0;
int price=0;
char title[100];
printf("entered\n");
while(i<n)
{
if(strncmp((char*)&arr[i],"title=",sizeof("title="))==0)
{
printf("cool [[[[[[[");
int x=0;
while(arr[x]!='\r')
{
printf("%c\n",arr[x]);
}
printf("\n");
}
i++;
}
printf("\n");
}
int process(int size,char buffer[size],char status)
{
int i=0;
int line_len=0;
char *line=malloc(sizeof(char) *150);
while(i<size)
{
if(strncmp((void *)&buffer[i],"style9.css",strlen("style9.css"))==0)
return 3;
if(strncmp((void *)&buffer[i],"GET / HTTP/1.1",14)==0)
{
while(buffer[i]!='\n')
{
line[line_len]=buffer[i];
line_len++;
i++;
}
//line[line_len]='\0';
//printf("%s\n",line);
memset(line,0,line_len);
line_len=0;
return 2;
}
if(strncmp((void*)&buffer[i],"add?",strlen("add?"))==0)
{
save_ad(size-i,(void*)&buffer[i]);
}
i++;
line_len++;
}
return 2;
}
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
{
off_t orig;
if (offset != NULL) {
/* Save current file offset and set offset to value in '*offset' */
orig = lseek(in_fd, 0, SEEK_CUR);
if (orig == -1)
return -1;
if (lseek(in_fd, *offset, SEEK_SET) == -1)
return -1;
}
size_t totSent = 0;
while (count > 0) {
size_t toRead = min(BUF_SIZE, count);
char buf[BUF_SIZE];
ssize_t numRead = read(in_fd, buf, toRead);
if (numRead == -1)
return -1;
if (numRead == 0)
break; /* EOF */
ssize_t numSent = write(out_fd, buf, numRead);
if (numSent == -1)
return -1;
if (numSent == 0) /* Should never happen */
printf("fatal: should never happen");
//fatal("sendfile: write() transferred 0 bytes");
count -= numSent;
totSent += numSent;
}
if (offset != NULL) {
/* Return updated file offset in '*offset', and reset the file offset
to the value it had when we were called. */
*offset = lseek(in_fd, 0, SEEK_CUR);
if (*offset == -1)
return -1;
if (lseek(in_fd, orig, SEEK_SET) == -1)
return -1;
}
return totSent;
}
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1000] = {0};
int get_return321;
//GET /css/style.css HTTP/1.1
char *hello = "HTTP/1.1 200 Okay\r\nContent-Type: text/html; charset=ISO-8859-4 \r\n\r\n";
//"HTTP/1.1 200 OK\\r\\n" \
"Content-Length: 55\r\n\n Content-Type: application/json\r\n '{\"name\":\"fawad\"}'";
//struct stat sb;
char *hello1 = "HTTP/1.1 200 Okay\r\nContent-Type: text/css\r\n\r\n";
struct stat sb_html;
struct stat sb_css;
int fd_in_html;//=open("/home/fawad/Desktop/C-work/html9.html",O_RDONLY);
const char* filename_html="/home/fawad/Desktop/C-work/temp.html";
int fd_in_css;//=open("/home/fawad/Desktop/C-work/css/style9.css",O_RDONLY);
const char* filename_css="/home/fawad/Desktop/C-work/css/style9.css";
//printf("%lu\n",sb_css.st_size);
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
//exit(EXIT_FAILURE);
}
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,&opt, sizeof(opt)))
{
perror("setsockopt");
//exit(EXIT_FAILURE);
}
/*if( setsockopt(server_fd, SOL_SOCKET, SO_SNDBUF, &sb.st_size, sizeof(sb.st_size)))
{
printf("sockopt\n");
}*/
/*int state = 1;
if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &state, sizeof(state)))
{
printf("sockopt\n");
}*/
int state = 1;
if(setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state)))
{
printf("TCP CORK\n");
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
if (bind(server_fd, (struct sockaddr *)&address,sizeof(address))<0)
{
perror("bind failed");
//exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
//exit(EXIT_FAILURE);
}
while(1)
{
printf("in loop\n");
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
// exit(EXIT_FAILURE);
}
printf("request came\n");
valread = read( new_socket , buffer, (1000));
//printf("%s\n",buffer );
printf("_________________________________\n");
//printf("%s\n",buffer);
get_return321=process(900,buffer,'r');
buffer[499]='\0';
printf("\n");
printf("\n");
if(get_return321==2)
{
send(new_socket , hello , strlen(hello) , 0 );
//send(new_socket , buffer_html , sb_html.st_size , 0 );
fd_in_html=open("/home/fawad/Desktop/C-work/temp.html",O_RDONLY);
if (stat(filename_html, &sb_html) == -1)
{
printf("%d\n",errno);
//exit(EXIT_FAILURE);
}
sendfile(new_socket,fd_in_html,0,sb_html.st_size);
close(fd_in_html);
printf("html sent\n");
}
if(get_return321==3)
{
send(new_socket , hello1 , sb_css.st_size , 0 );
fd_in_css=open("/home/fawad/Desktop/C-work/css/style9.css",O_RDONLY);
if (stat(filename_css, &sb_css) == -1)
{
printf("%d\n",errno);
//exit(EXIT_FAILURE);
}
sendfile(new_socket,fd_in_css,0,sb_css.st_size);
printf("3 reached\n");
close(fd_in_css);
}
close(new_socket);
state = 0;
setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
//close(new_socket);
state = 1;
setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
}
//close(fd_in);
close(fd_in_html);
}
Run Code Online (Sandbox Code Playgroud)
改变
if(strncmp((char*)&arr[i],"title=",sizeof("title="))==0)
Run Code Online (Sandbox Code Playgroud)
到
if(strncmp((char*)&arr[i],"title=",strlen("title="))==0)
Run Code Online (Sandbox Code Playgroud)
将为sizeof您提供 7,因为终止零包含在大小中。因此,当您使用时,sizeof您会比较太多的字符。
使用strlen会给你 6 这就是你想要的。
顺便说一句:不需要演员阵容。&arr[i]已经是一个char*
简单的例子:
char* arr = "add?title=samsung&price=2200";
// Using sizeof
if(strncmp(&arr[4],"title=",sizeof("title="))==0)
{
puts("match with sizeof");
}
else
{
puts("no match with sizeof");
}
// Using strlen
if(strncmp(&arr[4],"title=",strlen("title="))==0)
{
puts("match with strlen");
}
else
{
puts("no match with strlen");
}
Run Code Online (Sandbox Code Playgroud)
输出:
no match with sizeof
match with strlen
Run Code Online (Sandbox Code Playgroud)