📄 proxy1.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#define BUF_SIZE 1500 /* block transfer size */
#define QUEUE_SIZE 10
int content_length = -1;
int head_length = 0;
int port = 80;
int len = 0;/*the length of the domain name*/
void
fatal(char *string)
{
printf("%s\n", string);
exit(1);
}
void
getDomainName(char name[], char buffer[])
{
int i = 0, j = 0, k = 0;
for (i = 0; i < BUF_SIZE; i++) {
if (buffer[i] == 'H' && buffer[i + 1] == 'o' && buffer[i + 2] == 's' /*host*/
&& buffer[i + 3] == 't') {
i = i + 6;
j = i;
for (; j < BUF_SIZE; j++) {
if (buffer[j] == '\r' && buffer[j + 1] == '\n') { /*enter*/
memcpy(name, buffer + i, j - i); /*name*/
len = j - i;
//printf("j=%d , i=%d\n", j, i);
return;
}
}
}
}
}
int
getPort(char name[])
{
int i = len - 1;
for (; i > len - 7; i--) {/*the last 6 char*/
if (name[i] == ':') {
int p = 0;
char num[5] = " ";
memcpy(num, name + i + 1, len - 1 - i);/*port*/
//delete: from name
for (; i <= len - 1; i++)
name[i] = ' ';
p = atoi(num); /*change string to integer*/
printf("port in loop=%d\n", p);
return p;
}
}
return 80;
}
int
pickContentLength(char buffer[], int reads)
{
int i = 0, j = 0;
head_length = 0;
for (; head_length < reads; head_length++) {
if (buffer[head_length] == '\r' && buffer[head_length + 3] == '\n') {
head_length += 4;
break;
}
}/* a new line*/
i = 0;
j = 0;
content_length = -1;
for (; i < reads; i++) {
if (buffer[i] == '-' && buffer[i + 1] == 'L' && buffer[i + 2] == 'e' /*-Length:*/
&& buffer[i + 3] == 'n' && buffer[i + 4] == 'g'
&& buffer[i + 5] == 't' && buffer[i + 7] == ':') {
char length[100] = " ";
i = i + 9;/*skip -Length:*/
j = i;
for (; j < reads; j++) {
if (buffer[j] == '\r' && buffer[j + 1] == '\n') {/*a new line*/
memcpy(length, buffer + i, j - i);/*string between*/
content_length = atoi(length);
return content_length;
}
}
}
}
return -1;
}
int
checkHost(char name[])
{
int i = 0;
int has = 0;
for (; i < 100; i++) {
if (name[i + 6] == '.' && name[i] == 'g' && name[i + 5] == 'e'
&& name[i + 3] == 'g' && name[i + 1] == 'o') /*go g e.*/
has = 1;
if (name[i] = '.' && name[i + 1] == 'e' && name[i + 2] == 'd'
&& name[i + 3] == 'u' && name[i + 4] == '.') /*.edu.*/
has = 1;
}
return has;
}
int
main(int argc, char *argv[])
{
if (argc < 5) {
printf("Arguments must like:./proxy1 -l port1 -t machine:port2\nSample:./proxy1 -l 3000 -t localhost:8000\n");
exit(1);
}
if (argc > 5) {
printf("Arguments must like:./proxy1 -l port1 -t machine:port2\nSample:./proxy1 -l 3000 -t localhost:8000\n");
exit(2);
} char *myport = argv[2], *deip=argv[4];
//server variables
int s, b, l, fd, sa, bytes, on = 1;
char buf[BUF_SIZE]; /* buffer for outgoing file */
struct sockaddr_in channel; /* holds IP address */
//client variables
int c_cli, s_cli, bytes_cli;
char buf_cli[BUF_SIZE]; /* buffer for incoming file */
struct hostent *h_cli; /* info about server */
struct sockaddr_in channel_cli; /* holds IP address */
/* Build address structure to bind to socket. */
memset(&channel, 0, sizeof(channel)); /* zerochannel void *memset(void *s, char ch, unsigned n);*/
channel.sin_family = AF_INET;
channel.sin_addr.s_addr = htonl(INADDR_ANY);
channel.sin_port = htons(atoi(myport)); /*3000*/
/* Passive open. Wait for connection. */
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* createsocket */
if (s < 0)
fatal("socket failed");
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on));
b = bind(s, (struct sockaddr *) & channel, sizeof(channel));
if (b < 0)
fatal("bind failed");
l = listen(s, QUEUE_SIZE); /* specify queue size */
if (l < 0)
fatal("listen failed");
/*
* Socket is now set up and bound. Wait for connection and process
* it.
*/
while (1) {
printf("Listening for socket connection...\n");
sa = accept(s, 0, 0); /* block for connection request */ printf("accept\n");
if (sa < 0) {
printf("sa failed\n");
continue;
}
int r1 = read(sa, buf, BUF_SIZE); /* read file name from * socket */
char domainName[250] = " ";
getDomainName(domainName, buf); printf("before get port!\nThe domainName=%s\n",domainName);
port = getPort(domainName);
if (port != 80) {
printf("Unsupported port !%d \n", port);
continue;
}
h_cli = gethostbyname(domainName); /* look up host's IP
* address */
if (!h_cli) {
printf("gethostbyname failed\n");
continue;
}
s_cli = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s_cli < 0) {
printf("socket error\n");
continue;
} printf("\nstart hostent\n"); struct hostent *h_udp; char udp_name[50]=" "; char udp_port[50]=" "; int i=0,j=0; while(!(deip[j]=='\0')){ if(deip[j]==':'){ i=j; } j++; //printf("The char in domainname:%c ",deip[i]); } memcpy(udp_name, deip, i); printf("The domain name = %s",udp_name); memcpy(udp_port, deip+i+1,j-i-1); printf("The port = %s",udp_port); h_udp = gethostbyname(udp_name); if(!h_udp){ printf("gethostbyname failed\n");
continue; } /*memset(&channel_cli, 0, sizeof(channel_cli));
channel_cli.sin_family = AF_INET;
memcpy(&channel_cli.sin_addr.s_addr, h_cli->h_addr, h_cli->h_length);
channel_cli.sin_port = htons(port);*/
memset(&channel_cli, 0, sizeof(channel_cli)); channel_cli.sin_family = AF_INET;
memcpy(&channel_cli.sin_addr.s_addr, h_udp->h_addr, h_udp->h_length);
channel_cli.sin_port = htons(atoi(udp_port));
int addr_len=sizeof(channel_cli); c_cli = sendto(s_cli, buf, BUF_SIZE, 0, (struct sockaddr *)&channel_cli,addr_len);
if (c_cli < 0) {
printf("Failed to send to UDP\n");
continue;
}
int check = checkHost(domainName);
bytes_cli = recvfrom(s_cli,buf_cli,BUF_SIZE,0 ,(struct sockaddr *)&channel_cli ,&addr_len);
content_length = pickContentLength(buf_cli, bytes_cli);
printf("content_length=%d\n", content_length);
int content_length_fixed = content_length;
write(sa, buf_cli, bytes_cli);
int tail = bytes_cli - head_length;/*head_length=1*/
content_length = content_length - tail;
if (content_length_fixed <= -1) {
while (1) {
/*bytes_cli = read(s_cli, buf_cli, BUF_SIZE); /* read from socket */ bytes_cli = recvfrom(s_cli,buf_cli,BUF_SIZE,0 ,(struct sockaddr *)&channel_cli ,&addr_len);
printf("[Chunck: Bytes Read]: %d \n", bytes_cli);
write(sa, buf_cli, bytes_cli); /* write back to host */
if (bytes_cli <= 0) {
printf("Chunck:Read data OK!\n");
break; /* check for end of file */
}
}
}
if (content_length > 0) {
while (content_length > 0) {
/*bytes_cli = read(s_cli, buf_cli, BUF_SIZE); /* read from socket */ bytes_cli = recvfrom(s_cli,buf_cli,BUF_SIZE,0 ,(struct sockaddr *)&channel_cli ,&addr_len);
write(sa, buf_cli, bytes_cli); /* write back to host */
content_length -= bytes_cli;
printf("Bytes Read: %d\n", bytes_cli);
if (bytes_cli <= 0) {
printf("Read data OK!\n");
break; /* check for end of file */
}
}
}
printf("Now close sa\n");
close(sa); /* close connection */
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -