C套接字:将请求转发到端口80并读取响应

C套接字:将请求转发到端口80并读取响应,c,sockets,proxy,C,Sockets,Proxy,我有以下代码(我正在从代码处工作),我正试图将其转换为代理服务器: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h>

我有以下代码(我正在从代码处工作),我正试图将其转换为代理服务器:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

void dostuff(int); /* function prototype */
void error(const char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
     //setup proxy:
     int sockfd, newsockfd, portno, pid;
     socklen_t clilen;
     struct sockaddr_in serv_addr, cli_addr;

     if (argc < 2) {
         fprintf(stderr,"***ERROR, no port provided\n");
         exit(1);
     }
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (sockfd < 0)
        error("***ERROR opening socket");
     bzero((char *) &serv_addr, 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);
     if (bind(sockfd, (struct sockaddr *) &serv_addr,
              sizeof(serv_addr)) < 0)
              error("***ERROR on binding");
     listen(sockfd,5);
     clilen = sizeof(cli_addr);
     while (1) {
         newsockfd = accept(sockfd,
               (struct sockaddr *) &cli_addr, &clilen);
         if (newsockfd < 0)
             error("***ERROR on accept");
         pid = fork();
         if (pid < 0)
             error("***ERROR on fork");
             if (pid == 0)  {
             close(sockfd);
             dostuff(newsockfd);
             exit(0);
         }
         else close(newsockfd);
     } /* end of while */
     close(sockfd);
     return 0; /* we never get here */
}

/******** DOSTUFF() *********************
 There is a separate instance of this function 
 for each connection.  It handles all communication
 once a connnection has been established.
 *****************************************/
void dostuff (int sock)
{
   int n;
   char buffer[256];

   bzero(buffer,256);
   n = read(sock,buffer,255);
   if (n < 0){
       error("***ERROR reading from socket");
   }
   //printf("Here is the message: %s\n",buffer);




   /*
   ***Forward message to port 80 and read response here
   */





   n = write(sock,"I got your message",18);
   if (n < 0) error("***ERROR writing to socket");
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
void dostuff(int);/*功能原型*/
无效错误(常量字符*消息)
{
佩罗尔(味精);
出口(1);
}
int main(int argc,char*argv[])
{
//安装代理:
int sockfd、newsockfd、端口号、pid;
socklen_t clilen;
服务地址中的结构sockaddr\u,cli\u addr;
如果(argc<2){
fprintf(stderr,“***错误,未提供端口\n”);
出口(1);
}
sockfd=套接字(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
错误(“***打开套接字时出错”);
bzero((char*)&serv_addr,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(端口号);
如果(绑定(sockfd,(结构sockaddr*)和服务地址,
sizeof(服务地址))<0)
错误(“***绑定错误”);
听(sockfd,5);
clilen=sizeof(cli_addr);
而(1){
newsockfd=接受(sockfd,
(结构sockaddr*)和cli_addr和clilen);
if(newsockfd<0)
错误(“***接受错误”);
pid=fork();
if(pid<0)
错误(“fork上的***错误”);
如果(pid==0){
关闭(sockfd);
dostuff(newsockfd);
出口(0);
}
否则关闭(newsockfd);
}/*结束时*/
关闭(sockfd);
返回0;/*我们永远无法到达这里*/
}
/********多斯塔夫()*********************
此函数有一个单独的实例
对于每个连接。它处理所有的通信
一旦建立了连接。
*****************************************/
空隙度凝灰岩(内部短袜)
{
int n;
字符缓冲区[256];
b0(缓冲器,256);
n=读取(sock,缓冲区,255);
if(n<0){
错误(“***从套接字读取错误”);
}
//printf(“这是消息:%s\n”,缓冲区);
/*
***将消息转发到端口80并在此处读取响应
*/
n=写(sock,“我收到你的消息”,18);
if(n<0)错误(“***写入套接字错误”);
}
在函数“dostuff”中,我想将“buffer”写入端口80,读取响应并将此响应写回端口20000(argv[1])

目前,当我将浏览器的代理设置为172.16.1.218:20000时,我得到的只是“我收到了你的消息”。我想将此更改为网页上的响应

非常感谢任何指向正确方向的指针

以下是我迄今为止所做的尝试(用以下代码替换多行注释“将消息转发到端口80并在此处读取响应”):

int,新墨西哥州波特诺;
serv_addri中的结构sockaddr_;
结构主机*serveri;
波尔图尼=80;
sockfdi=socket(AF_INET,SOCK_STREAM,0);
if(小于0){
错误(“***打开套接字时出错”);
}
serveri=gethostbyname(“172.16.1.218”);
if(serveri==NULL){
fprintf(stderr,“***错误,没有这样的主机\n”);
出口(0);
}
bzero((char*)&serv_addri,sizeof(serv_addri));
serv_addri.sin_family=AF_INET;
b复制((char*)服务器i->h_addr,(char*)和serv_addri.sin_addr.s_addr,服务器i->h_长度);
serv_addri.sin_port=htons(portnoi);
if(connect(sockfdi,(struct sockaddr*)&serv_addri,sizeof(serv_addri))<0){
错误(“***连接错误”);
}
printf(“请输入消息:”);
b0(缓冲器,256);
但每次我尝试通过我的webbrowser连接时,服务器都会回答道:“***连接错误:连接被拒绝”


非常感谢,

这是一项非常重要的任务。目前,您缺少三件事,一件简单的事和两件困难的事:

  • 您必须打开到要将调用转发到的服务器的网络连接(非常简单,请参阅
    socket()
    connect()

  • 然后您将拥有一个双工连接,即两个并发数据流,一个从客户端到转发服务器,另一个从转发服务器到客户端。为了处理这种并发性,您需要两个具有阻塞I/O或某种非阻塞I/O的线程(请参见
    select()
    或AIO)

  • 如果将HTTP请求转发到另一台服务器而不做任何更改,则请求中可能会出现无效的服务器名称和IP地址。然后,请求将被拒绝。因此,您需要解析HTTP头,进行一些替换并转发修改后的HTTP请求


  • 哎哟听起来很棘手。。。我不知道我在这里干什么。谢谢你的洞察力。我想我会一步一步来。
       int sockfdi, portnoi, ni;
       struct sockaddr_in serv_addri;
       struct hostent *serveri;
       portnoi =80;
    
       sockfdi = socket(AF_INET, SOCK_STREAM, 0);
       if (sockfdi < 0){
            error("***ERROR opening socket");
       }
       serveri = gethostbyname("172.16.1.218");
       if (serveri == NULL){
           fprintf(stderr,"***ERROR, no such host\n");
           exit(0);
       }
    
       bzero((char *) &serv_addri, sizeof(serv_addri));
       serv_addri.sin_family = AF_INET;
       bcopy((char *)serveri->h_addr, (char *)&serv_addri.sin_addr.s_addr, serveri->h_length);
       serv_addri.sin_port = htons(portnoi);
       if (connect(sockfdi,(struct sockaddr *) &serv_addri,sizeof(serv_addri)) < 0){
           error("***ERROR connecting");
       }
       printf("Please enter the message: ");
       bzero(buffer,256);