将套接字进程转换为线程c

时间:2015-04-30 01:12:52

标签: c sockets pthreads

我有这个程序,我可以使用端口号运行,然后在浏览器中执行类似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替换分叉?

0 个答案:

没有答案