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