Sockets 套接字编程错误,“;“非插座上的插座操作”;

Sockets 套接字编程错误,“;“非插座上的插座操作”;,sockets,Sockets,这个问题已经被问过很多次了,但是通过搜索和实施一些对其他人有用的解决方案,我仍然无法找出我做错了什么。我在理解使用套接字编程时仍然有问题,因此,如有任何解释,我将不胜感激。我得到错误的函数是“int-forwardClientReq(char*buffer,char*hostname,int-clientfd)”,更具体地说是: numBytesSent = send(serverfd, buffer, strlen(buffer), 0); if(numBytesSent == -1)

这个问题已经被问过很多次了,但是通过搜索和实施一些对其他人有用的解决方案,我仍然无法找出我做错了什么。我在理解使用套接字编程时仍然有问题,因此,如有任何解释,我将不胜感激。我得到错误的函数是“int-forwardClientReq(char*buffer,char*hostname,int-clientfd)”,更具体地说是:

  numBytesSent = send(serverfd, buffer, strlen(buffer), 0);
  if(numBytesSent == -1)
      printf("Oh dear, something went wrong with send()! %s\n", strerror(errno));
完整代码如下:

/* Proxy application called webproxy */

// Copy past http server includes, remove unnecessary
#include <stdio.h>
#include <stdlib.h>
#include <string.h>      /* for fgets */
#include <strings.h>     /* for bzero, bcopy */
#include <unistd.h>      /* for read, write */
#include <sys/socket.h>  /* for socket use */
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <errno.h>

#define MAXBUF  8192  /* max text line length */
#define LISTENQ  1024  /* second argument to listen() */
#define ERRBUFSIZE 1024
#define HEAPBUF 32768 // 2^15

int open_listenfd(int port);
void webProxy(int connfd);
void *thread(void *vargp);
int connect2Client(char* ip, char* port);
void sendErrResponse(char* errBUF, int connfd);
int forwardClientReq(char* buffer, char* host, int clientfd);


int main(int argc, char **argv)
{
  int timeout = 0;
  /* Check if the function was called correctly */
  /* Store arguments provided (port number & cache timeout) */
  if(argc < 2  || argc > 3){
    fprintf(stderr, "Incorrect arguments, Usage: ./<executableFile> <port#> <timeout(optional)>\n");
    exit(0);
  }
  if(argc == 3)
    timeout = atoi(argv[2]);

  int listenfd, *connfdp, port, clientlen=sizeof(struct sockaddr_in);
  pthread_t tid;
  struct sockaddr_in clientaddr;

  port = atoi(argv[1]); // store the port number
  listenfd = open_listenfd(port); // create persistant TCP socket for client HTTP requests

  /* Create,Bind,Listen SOCKET and multithread */
  while (1) {
    connfdp = malloc(sizeof(int));  // pointer to pass the socket
    *connfdp = accept(listenfd, (struct sockaddr*)&clientaddr, &clientlen);
    if(*connfdp<0)
      printf("There is an error accepting the connection with the client");
    pthread_create(&tid, NULL, thread, connfdp);  // call thread function with tid
  }
}

/* thread routine */
void * thread(void * vargp)
{
    int connfd = *((int *)vargp);
    pthread_detach(pthread_self());
    free(vargp);
    webProxy(connfd);
    close(connfd);
    return NULL;
}

void webProxy(int connfd)
{
  size_t n;
  char buffer[MAXBUF];  // pointer to pass the socket
  char errorBuf[ERRBUFSIZE];
  bzero(errorBuf, ERRBUFSIZE);
  bzero(buffer, MAXBUF);
  char httpmsg[]="HTTP/1.1 200 Document Follows\r\nContent-Type:text/html\r\nContent-Length:32\r\n\r\n<html><h1>Hello CSCI4273 Course!</h1>";
  char hostname[50];

  n = read(connfd, buffer, MAXBUF);  // read the requst up to maxbuf sizeof
  printf("server received the following request:\n%s\n",buffer);


  /* parse the request */
  char requestType[50], fullPath[50];
  bzero(requestType, 50);
  bzero(fullPath, 50);
  sscanf(buffer, "%s %s", requestType, fullPath);
  printf("requestType = %s, and fullPath= %s\n", requestType, fullPath);
  /* I tried a million different methods and libary suggestions but this is the only
  method that I found to easily parse the information I wanted to input */
  // sscanf(fullPath, "http://www.%511[^/\n]", hostname);
  sscanf(fullPath, "http://%511[^/\n]", hostname);
  printf("hostname is = %s\n", hostname);


  /* support only GET requests */
  if(strcmp(requestType, "GET") != 0)
  {
    printf("Proxy received a request that was not a 'GET' Request, sending 400 Bad Request response\n");
    sendErrResponse(errorBuf, connfd);
  }
  // // /* support only HTTP/1.1 */
  // else if(strcmp(Type, "HTTP/1.1") != 0)
  // {
  //   printf("Proxy received a request that was not an HTTP/1.1 version, sending 400 Bad Request response");
  //   // I think the error message below is 80, but I could be wrong. Need to double check or use strlen function
  //   sprintf(errorBuf, "HTTP/1.1 400 Bad Request\r\nContent-Type:text/html\r\nContent-Length: %d\r\n\r\n",80);
  //   write(connfd, errorBuf, strlen(errorBuf));
  //   bzero(errorBuf, ERRBUFSIZE);
  // }

  /* parse and verify the hostname/server */
  struct hostent *host = gethostbyname(hostname);
  if (host == NULL) {
      fprintf(stderr,"ERROR, no such host as %s\n", hostname);
      sendErrResponse(errorBuf, connfd);
      exit(0);
  }
  else{
    /* Forward request to HTTP server */
    forwardClientReq(buffer, hostname, connfd);
    printf("buffer = %s\n", buffer);

    /* Relay data from server to client */
  }


}

int forwardClientReq(char* buffer, char* hostname, int clientfd)
{
  char* serverResponse = malloc(HEAPBUF);  // create a buffer for receiving the response from the server
  bzero(serverResponse, HEAPBUF); // zeroize the buffer

  /* open a socket with the server */
  struct sockaddr_in serveraddr;
  int serverSock, optval =1;

  /* Create a socket descriptor */
  if(-1 == (serverSock = socket(AF_INET, SOCK_STREAM, 0)))  // yoda condition...
  {
    printf("Error: Unable to create socket in 'open_listenfd' function");
    return -1;
  }
  /* Eliminates "Address already in use" error from bind. */
  if (setsockopt(serverSock, SOL_SOCKET, SO_REUSEADDR, &optval , sizeof(int)) < 0){
    printf("Error in setsockopt in forwardClientReq function");
    return -1;
  }

  struct hostent* host = gethostbyname(hostname);

  serveraddr.sin_family = AF_INET;
  memcpy(&serveraddr.sin_addr, host->h_addr_list[0], host->h_length);
  serveraddr.sin_port = htons(80); //(you should pick the correct remote port or use the default 80 port if noneis specified).

  socklen_t addrlen = sizeof(serveraddr); // The addrlen argument specifies the size of serveraddr.
  int serverfd = connect(serverSock, (struct sockaddr*) &serveraddr, addrlen);
  if(serverfd < 0)
    printf("improper connection when trying to forward client's request/n");


  /* send the client message to the server */
  int numBytesSent = 0;
  printf("buffer before send = %s\n", buffer);
  sprintf(buffer, "\r\n\r\n");
  numBytesSent = send(serverfd, buffer, strlen(buffer), 0);
  if(numBytesSent == -1)
      printf("Oh dear, something went wrong with send()! %s\n", strerror(errno));
  // printf("Sent %d to the server", numBytesSent);

  // /* store the server's response */
  // int numBytesRead = 0;
  // numBytesRead = read(serverfd, serverResponse, HEAPBUF);
  // printf("Sent %d to the server", numBytesRead);
  //
  // /* send the response to the client. This is a moment here the proxy can cache the page,
  // inspect the data, and do all kinds of cool proxy-level things */
  // numBytesSent = write(clientfd, serverResponse, strlen(serverResponse));
  // printf("Sent %d to the server", numBytesSent);

  free(serverResponse); // free malloc'd space
}

int open_listenfd(int port)
{
    int listenfd, optval=1;
    struct sockaddr_in serveraddr;

    /* Create a socket descriptor */
    if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
      printf("Error: Unable to create socket in 'open_listenfd' function");
      return -1;
    }
    /* Eliminates "Address already in use" error from bind. */
    if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &optval , sizeof(int)) < 0)
        return -1;
    /* listenfd will be an endpoint for all requests to port
       on any IP address for this host */
    bzero((char *) &serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons((unsigned short)port);
    /* bind: associate the parent socket with a port */
    if (bind(listenfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)
        return -1;
    /* Make it a listening socket ready to accept connection requests */
    if (listen(listenfd, LISTENQ) < 0)
        return -1;
    return listenfd;
} /* end open_listenfd */

void sendErrResponse(char* errorBuf, int connfd)
{
  // I think the error message below is 80, but I could be wrong. Need to double check or use strlen function
  sprintf(errorBuf, "HTTP/1.1 400 Bad Request\r\nContent-Type:text/html\r\nContent-Length: %d\r\n\r\n",80);
  write(connfd, errorBuf, strlen(errorBuf));
  bzero(errorBuf, ERRBUFSIZE);
}
/*名为webproxy的代理应用程序*/
//复制过去的http服务器包括,删除不必要的
#包括
#包括
#包括/*用于FGET*/
#包括/*用于bzero,b复制*/
#包括/*用于读、写*/
#包括/*插座使用*/
#包括
#包括
#包括
#包括
#包括
#定义MAXBUF 8192/*最大文本行长度*/
#定义LISTENQ 1024/*第二个参数以侦听()*/
#定义errbufsize1024
#定义HEAPBUF 32768//2^15
int open_listenfd(int端口);
无效网络代理(int connfd);
void*螺纹(void*vargp);
int connect2Client(字符*ip,字符*端口);
void senderresponse(char*errBUF,int connfd);
int forwardClientReq(字符*缓冲区,字符*主机,int clientfd);
int main(int argc,字符**argv)
{
int超时=0;
/*检查函数调用是否正确*/
/*提供的存储参数(端口号和缓存超时)*/
如果(argc<2 | | argc>3){
fprintf(stderr,“不正确的参数,用法:./\n”);
出口(0);
}
如果(argc==3)
超时=atoi(argv[2]);
int listenfd,*connfdp,port,clientlen=sizeof(struct sockaddr_in);
pthread_t tid;
clientaddr中的结构sockaddr_;
port=atoi(argv[1]);//存储端口号
listenfd=open_listenfd(port);//为客户端HTTP请求创建持久TCP套接字
/*创建、绑定、侦听套接字和多线程*/
而(1){
connfdp=malloc(sizeof(int));//传递套接字的指针
*connfdp=accept(listenfd,(struct sockaddr*)&clientaddr,&clientlen);
if(*connfdph\u addr\u list[0],host->h\u length);
serveraddr.sin_port=htons(80);/(如果未指定,则应选择正确的远程端口或使用默认的80端口)。
socklen_t addrlen=sizeof(serveraddr);//addrlen参数指定serveraddr的大小。
int serverfd=connect(serverSock,(struct sockaddr*)&serveraddr,addrlen);
if(serverfd<0)
printf(“尝试转发客户请求时连接不正确/n”);
/*将客户端消息发送到服务器*/
int numbytestsent=0;
printf(“发送前缓冲区=%s\n”,缓冲区);
sprintf(缓冲区“\r\n\r\n”);
numbytestsent=send(serverfd,buffer,strlen(buffer),0);
如果(numbytestsent==-1)
printf(“哦,天哪,send()出现了问题!%s\n”,strerror(errno));
//printf(“已将%d发送到服务器”,numbytestsent);
///*存储服务器的响应*/
//int numBytesRead=0;
//numBytesRead=read(serverfd、serverResponse、HEAPBUF);
//printf(“已将%d发送到服务器”,numbytsread);
//
///*将响应发送到客户端。此时代理可以缓存页面,
//检查数据,做各种很酷的代理级别的事情*/
//numbytestsent=write(clientfd、serverResponse、strlen(serverResponse));
//printf(“已将%d发送到服务器”,numbytestsent);
free(serverResponse);//释放malloc'd空间
}
int open_listenfd(int端口)
{
int listenfd,optval=1;
serveraddr中的结构sockaddr\u;
/*创建套接字描述符*/
if((listenfd=socket(AF_INET,SOCK_STREAM,0))<0)
{
printf(“错误:无法在‘open_listenfd’函数中创建套接字”);
返回-1;
}
/*消除绑定中的“地址已在使用”错误*/
if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(int))<0)
返回-1;
/*listenfd将是对端口的所有请求的端点
在该主机的任何IP地址上*/
bzero((char*)&serveraddr,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin\u addr.s\u addr=htonl(INADDR\u ANY);
serveraddr.sin_port=htons((无符号短)端口);
/*绑定:将父套接字与端口关联*/
if(bind(listenfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr))<0
返回-1;
/*将其设置为侦听套接字,以便随时接受连接请求*/
if(listen(listenfd,LISTENQ)<0)
返回-1;
返回listenfd;
}/*结束打开\u列出*/
无效SenderResponse(char*errorBuf,int-connfd)
{
//我想下面的错误信息是80,但我可能是错的。需要再次检查或使用strlen功能
sprintf(errorBuf,“HTTP/1.1 400错误请求\r\n内容类型:text/html\r\n内容长度:%d\r\n\r\n”,80);
写入(connfd、errorBuf、strlen(errorBuf));
bzero(errorBuf,ERRBUFSIZE);
}
的返回值是错误代码而不是套接字fd:

如果连接或绑定成功,则返回零, -返回1,并正确设置errno

所以

应该是

numBytesSent = send(serverSock, buffer, strlen(buffer), 0);
的返回值是错误代码,而不是套接字fd:

如果连接或绑定成功,则返回零, -返回1,并正确设置errno

所以

应该是

numBytesSent = send(serverSock, buffer, strlen(buffer), 0);

是的,那是肯定的。谢谢你。我听不懂让人伤心,但是,几乎总是C中的小东西。你摇滚。是的,那是肯定的。谢谢你。我听不懂让人伤心,但是,几乎总是C中的小东西。你摇滚。