我有这个程序,我可以使用端口号运行,然后在浏览器中执行类似localhost:port / image.jpg的操作,它将打开图像。但是我想尝试使用线程来做这件事。
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#define BufferSize 1024 // for parsing request
#define BIG_ENUF 4096 // For request header
void error(char *); // prototype for quick error exit
int main(int argc, char *argv[]) // arv[1] has port #
{
int sockfd, newsockfd, portno, clilen,Connect_Count=0;
char buffer[BufferSize]; // for communicating with client
char * BigBuffer; // for serving file to client
int BufferNdx,n ;// workaday subscripts
char * TmpBuffer, *SavePtr, *FileName, *GetToken;
pid_t pid; // for forks;
FILE * F; // for streaming file when GET served
struct stat S;// to find file length
struct sockaddr_in serv_addr, cli_addr;
// structs for client and server
if (argc < 2) { // looking for port #
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
// specifies TCP IP flow
if (sockfd < 0)error("ERROR opening socket");
memset( (char *) &serv_addr, 0, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno); // proper byte order
if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR on binding");
GetToken = strtok_r(TmpBuffer," ",&SavePtr);
// And Now port is bound to socket for TCP / IP
while (Connect_Count < 10) // Limit on Number of Connections
{listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
// listen blocks until someone knocks and when we accept
// the client structure is filled by accept
if (newsockfd < 0) // exit server if bad accept
error( "ERROR on accept");
// otherwise let's fork a process to do that work
pid = fork();
if (pid < 0) error("bad fork\n");
if (pid == 0) break;
// to handle talking with client below
//if parent, loop again to listen if more connections ?
}
// ===================================================
// Forked child
memset(buffer, 0,BufferSize);
n = read(newsockfd,buffer,BufferSize-1); // This leaves null at end
if (n < 0) error("ERROR reading from socket");
printf("%s\n",(TmpBuffer=strtok_r(buffer,"\n",&SavePtr)));
GetToken = strtok_r(TmpBuffer," ",&SavePtr);
printf("%s\n",GetToken);
GetToken = strtok_r(NULL," ",&SavePtr);
printf("%s After Get\n",GetToken); // file name token begins '/'
GetToken++; // Point to first character of actual file name
// now open the file and send it to client ?
if ((F = fopen(GetToken,"r")) == NULL) error("Bad\n");
else printf("Good\n");
int FileSize;
if ((fstat(fileno(F),&S)==-1)) error("failed fstat\n"); // Need file size
FileSize = S.st_size;
char Response[BIG_ENUF];int HeaderCount=0;
HeaderCount=0;//Use to know where to fill buffer with sprintf
HeaderCount+=sprintf( Response+HeaderCount,"HTTP/1.0 200 OK\r\n");
HeaderCount+=sprintf( Response+HeaderCount,"Server: Flaky Server/1.0.0\r\n");
HeaderCount+=sprintf( Response+HeaderCount,"Content-Type: image/jpeg\r\n");
HeaderCount+=sprintf( Response+HeaderCount,"Content-Length:%d\r\n",FileSize);
//delimit header
HeaderCount+=sprintf( Response+HeaderCount,"\r\n");
fprintf(stderr,"HeaderCount %d and Header\n",HeaderCount);
write(STDERR_FILENO, Response, HeaderCount);
write(newsockfd,Response,HeaderCount); // and send to client
BigBuffer = malloc(FileSize+2);
fread(BigBuffer,1,FileSize,F);
write(newsockfd,BigBuffer,FileSize);
free(BigBuffer);
// Now close up this client
close(newsockfd);
return 0;
}
// bad error routine
void error(char *msg)
{
perror(msg);
exit(1);
}
我正在尝试将这些进程转换为线程程序。我对线程很新。但是将我在子进程下标记的所有内容移动到线程函数的基本概念是什么?并用pthread_create替换分叉?