我试着用Beej套接字编程指南写了这个。很明显我做错了什么吗?是否存在缓冲区溢出的可能性?分割故障?有什么可能的错误,我没有检查?
或者我做得太过火了?
非常感谢。
/*
* sk2.c
*
* Created on: May 26, 2013
* Author: bharath
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <regex.h>
#define BUFSIZE 1025
int main(int argC, char *argv[]){
struct addrinfo hints, *results, *p;
int status, s,con1, rret;
char ipstr[INET6_ADDRSTRLEN];
printf("Bharath's Socket Program\n");
memset(&hints,0,sizeof hints);
hints.ai_family=AF_UNSPEC;
hints.ai_socktype=SOCK_STREAM;
if (argC<2){
fprintf(stderr,"No URI given.\n");
return -1;
}
regex_t fqdnParser, resourceParser;
regmatch_t m;
char *fqdn, *resource;
if (!regcomp(&fqdnParser,"^[a-zA-Z0-9.]*",0)){
char *buff = argv[1];
if (!regexec(&fqdnParser, argv[1], 1, &m, 0)){
fqdn=(char*)malloc(m.rm_eo-m.rm_so+1);
snprintf (fqdn,m.rm_eo-m.rm_so+1,"%.*s \n", m.rm_eo, buff+m.rm_so);
*(fqdn+m.rm_eo-m.rm_so)=0;
}else{
fprintf(stderr,"Bad URI FQDN.\n");
return -1;
}
if (!regcomp(&resourceParser,"/.*$",0)){
if (!regexec(&resourceParser, argv[1], 1, &m, 0)){
resource=(char*)malloc(m.rm_eo-m.rm_so+1);
snprintf (resource,m.rm_eo-m.rm_so+1,"%.*s \n", m.rm_eo, buff+m.rm_so);
*(resource+m.rm_eo-m.rm_so)=0;
}
else{
resource="/";
}
printf("Parsed: [ %s ][ %s ]\n",fqdn,resource);
}
}else{
fprintf(stderr,"RegEx not compiled.\n");
}
regfree(&fqdnParser);
regfree(&resourceParser);
if ((status=getaddrinfo(fqdn,"http",&hints,&results))!=0){
fprintf(stderr,"Error: %s\n",gai_strerror(status));
return -2;
}
for(p=results; p!=NULL; p=p->ai_next){
char *ipver;
void *addr;
//ipver=malloc(5);
if (p->ai_family==AF_INET){
ipver="IPv4";
struct sockaddr_in *ipv4=(struct sockaddr_in*)p->ai_addr;
addr=&(ipv4->sin_addr);
}else if(p->ai_family==AF_INET6){
ipver="IPv6";
struct sockaddr_in6 *ipv6=(struct sockaddr_in6*)p->ai_addr;
addr=&(ipv6->sin6_addr);
}
inet_ntop(p->ai_family,addr,ipstr,sizeof ipstr);
printf("%s %s\n",ipver, ipstr);
if ((s=socket(p->ai_family,p->ai_socktype,p->ai_protocol))!=-1){
if (connect(s,p->ai_addr,p->ai_addrlen) == -1){
fprintf(stderr,"Error Connecting.");
}else{
char *req;
req=(char*)malloc(25+strlen(resource)+strlen(fqdn));
strcpy(req,"GET ");
strcat(req,resource);
strcat(req," HTTP/1.0\nHost: ");
strcat(req,fqdn);
strcat(req,"\n\n");
//printf("%d | %s",strlen(resource),req);
void *buf;
int len,b;
long int bc=0;
buf=malloc(BUFSIZE);
*(char*)(buf+BUFSIZE)=0;
len=strlen(req);
b=send(s,req,len,0);
printf("%d bytes sent\n--------------\n",b);
printf("%s\n-----------------\n",req);
b=0;
do{
if(b<BUFSIZE-1){
*(char*)(buf+b)=0;
}
printf("%s",(char*)buf);
bc+=b;
}while ((b=recv(s, buf, BUFSIZE-1, 0))>0);
close(s);
printf("\n--------------\n%ld bytes received.",bc);
free(buf);
break;
}
}else{
fprintf(stderr,"Socket not created: %d\n",s);
return -3;
}
}
return 0;
}发布于 2013-05-28 15:02:57
我对套接字不太了解,但这里有一些通用的C编程注释:
resource的malloc内存。如果您这样做了,那么当您试图释放()该内存时,resource="/";会使程序崩溃。char ipstr[INET6_ADDRSTRLEN];声明一个大小为“字符串长度”的数组是可疑的。您确定这为字符串空终止字符分配了足够的空间吗?(char*)malloc从来没有理由将malloc的结果投到C中,它甚至在C90中也有潜在的危害。您可以在堆栈溢出上找到有关这方面的无数主题。argC最常见的拼写是小写,argc。int* ptr1, ptr2; // ptr2 is not a pointer as intended这样的bug。memset(&hints,0,sizeof hints);等应该替换为struct addrinfo hints = { .ai_family=AF_UNSPEC; .ai_socktype=SOCK_STREAM; };,这使得代码更容易阅读,也可能稍微快一些。return -1替换为stdlib.h中的EXIT_FAILURE。同样,理想情况下,return 0应该被EXIT_SUCCESS取代。s,m,a,b,c这样的名字使程序难以阅读和理解。malloc(25+ ...。神奇的数字25可以被宏(如#define CONST_STRLEN (sizeof("GET ")-1 + sizeof(" HTTP/1.0\nHost: ")-1 + ... + 1) )所取代,这样人们才能真正理解到底发生了什么。https://codereview.stackexchange.com/questions/26683
复制相似问题