-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtcp_client3.c
More file actions
executable file
·159 lines (141 loc) · 4.28 KB
/
tcp_client3.c
File metadata and controls
executable file
·159 lines (141 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*******************************
tcp_client.c: the source file of the client in tcp transmission
********************************/
#include "headsock.h"
float str_cli(FILE *fp, int sockfd, long *len); //transmission function
void tv_sub(struct timeval *out, struct timeval *in); //calcu the time interval between out and in
int main(int argc, char **argv)
{
int sockfd, ret;
float ti, rt;
long len = 0;
struct sockaddr_in ser_addr;
char ** pptr;
struct hostent *sh;
struct in_addr **addrs;
FILE *fp;
if (argc != 2) {
printf("parameters not match");
}
sh = gethostbyname(argv[1]); //get host's information
if (sh == NULL) {
printf("error when gethostby name");
exit(0);
}
printf("canonical name: %s\n", sh->h_name); //print the remote host's information
for (pptr=sh->h_aliases; *pptr != NULL; pptr++)
printf("the aliases name is: %s\n", *pptr);
switch(sh->h_addrtype)
{
case AF_INET:
printf("AF_INET\n");
break;
default:
printf("unknown addrtype\n");
break;
}
addrs = (struct in_addr **)sh->h_addr_list;
sockfd = socket(AF_INET, SOCK_STREAM, 0); //create the socket
if (sockfd <0)
{
printf("error in socket");
exit(1);
}
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(MYTCP_PORT);
memcpy(&(ser_addr.sin_addr.s_addr), *addrs, sizeof(struct in_addr));
bzero(&(ser_addr.sin_zero), 8);
ret = connect(sockfd, (struct sockaddr *)&ser_addr, sizeof(struct sockaddr)); //connect the socket with the host
if (ret != 0) {
printf ("connection failed\n");
close(sockfd);
exit(1);
}
if((fp = fopen ("myfile.txt","r+t")) == NULL)
{
printf("File doesn't exit\n");
exit(0);
}
ti = str_cli(fp, sockfd, &len); //perform the transmission and receiving
rt = (len/(float)ti); //caculate the average transmission rate
printf("Time(ms) : %.3f, Data sent(byte): %d\nData rate: %f (Kbytes/s)\n", ti, (int)len, rt);
close(sockfd);
fclose(fp);
//}
exit(0);
}
float str_cli(FILE *fp, int sockfd, long *len)
{
char *buf;
long lsize, ci;
struct ack_so ack;
struct pack_so pack;
int n, slen;
float time_inv = 0.0;
struct timeval sendt, recvt;
struct timeval tv;
pack.len = 0;
pack.num = 0;
tv.tv_sec = 5; /* 5 Secs Timeout */
tv.tv_usec = 0; // Not init'ing this can cause strange errors
if(setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)) < 0) // set timeout
{
printf("setsockopt failed\n");
exit(1);
}
ci = 0;
fseek (fp , 0 , SEEK_END);
lsize = ftell (fp);
rewind (fp);
printf("The file length is %d bytes\n", (int)lsize);
printf("the packet length is %d bytes\n",DATALEN);
// allocate memory to contain the whole file.
buf = (char *) malloc (lsize);
if (buf == NULL) exit (2);
// copy the file into the buffer.
fread (buf,1,lsize,fp);
/*** the whole file is loaded in the buffer. ***/
buf[lsize] ='\0'; //append the end byte
gettimeofday(&sendt, NULL); //get the current time
while(ci<= lsize)
{
if ((lsize+1-ci) <= DATALEN)
slen = lsize+1-ci;
else
slen = DATALEN;
memcpy(pack.data, (buf+ci), slen);
pack.len = slen;
n = send(sockfd, &pack, sizeof(pack), 0);
if(n == -1) {
printf("cli: send error!"); //send the data
exit(1);
}
if ((n= recv(sockfd, &ack, sizeof(ack), 0))==-1) //receive the ack
{
printf("cli: error when receiving ack, start resending\n"); //normally timeout, need resend
}
else if (!(ack.num == !pack.num && ack.len == pack.len)) //data corrupted, need resend
{
//printf("error in transmission, start resending\n");
}
else //successful
{
ci += slen;
pack.num = !pack.num;
*len += sizeof(pack);
}
}
gettimeofday(&recvt, NULL); //get current time
tv_sub(&recvt, &sendt); // get the whole trans time
time_inv += (recvt.tv_sec)*1000.0 + (recvt.tv_usec)/1000.0;
return(time_inv);
}
void tv_sub(struct timeval *out, struct timeval *in)
{
if ((out->tv_usec -= in->tv_usec) <0)
{
--out ->tv_sec;
out ->tv_usec += 1000000;
}
out->tv_sec -= in->tv_sec;
}