嗨,我目前正在 UNIX 中编写一个 C 程序来为学校的套接字停止和等待协议建模。当我在命令行中输入 4 个参数时,我不断收到分段错误。如果我输入多于或少于 4,那么我会抛出正确的错误。如果有人可以提供帮助,将不胜感激。提前致谢。
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <stdlib.h>
#include <strings.h>
#define SERVER_PORT 6500
#define MAX_LINE 256
int
main(int argc, char * argv[])
{
FILE *fp;
struct hostent *hp;
struct sockaddr_in sin, client;
char *host;
char ack[MAX_LINE], buf[MAX_LINE], fname[MAX_LINE];
int s, i, rnum, drop;
int8_t current, last = -1;
int rval, slen, NFrames, len;
long LenFile;
struct timeval rectime; //The struct timeval structure represents an elapsed time
struct timeval zone;
if (argc==4){
host=argv[1];
}
else {
fprintf(stderr, "usage: simplex-talk host\n");
//fprintf(stderr, "hello");
exit(1);
}
if (!hp) {
fprintf(stderr, "simplex-talk: unknown host: %s\n", host);
exit(1);
}
bzero((char *)&sin, sizeof(sin));
sin.sin_family = AF_INET;
bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
sin.sin_port=htons(SERVER_PORT);
if((s=socket(PF_INET, SOCK_DGRAM,0)) < 0){
perror("simplex-talk; socket");
exit(1);
}
// create file request
sprintf(buf, "%s\0", argv[3]);
if ((rval=sendto(s,buf,sizeof(buf),0,(struct sockaddr *)&client,sizeof(client)))< 0) {
printf("sjkdfj");
perror("writing on datagram socket");
}
system("date");
printf("Sent request for file %s at time = %ld %ld\n", argv[3], rectime.tv_sec, rectime.tv_usec);
bzero(ack,sizeof(ack));
slen = sizeof(client);
buf[MAX_LINE-1] = '\0';
len = strlen(buf) + 1;
//request to send, waiting....
while ((rval = recvfrom(s,ack,sizeof(ack),0,(struct sockaddr *)&client,&slen))<0){
perror("receiver recvfrom");
printf(stderr, "hhhhhhhh");
}
//get time
if (gettimeofday(&rectime, &zone) < 0) {
perror("getting time");
exit(1);
}
if(ack[0] == '0'){
printf("Received file not found, time = %ld %ld, File = \"%s\"\n", rectime.tv_sec, rectime.tv_usec, fname);
}
if(ack[0] == '1') {
char ch[MAX_LINE];
int i, j;
for(i=2, j=0; ack[i] != ' '; i++, j++){
ch[j] = ack[i];
}
ch[i++] = '\0';
LenFile=atoi(ch);
for(j=0; ack[i] && ack[i] != '.'; i++, j++){
fname[j] = ack[i];
}
fname[i++] = '\0';
strcat(fname, "client.txt");
NFrames = LenFile / MAX_LINE + (LenFile % MAX_LINE == 0 ? 0:1);
printf("Received, ack sent, time = %ld %ld\nfname = \"%s\"\n", LenFile = "%d\n", rectime.tv_sec, rectime.tv_usec, fname, LenFile);
//file I/O (reads)
fp=fopen(fname, "w");
if(fp==NULL){
perror("Opening File for Writing");
exit(1);
}
printf("Opening File %s for writing\n", fname);
drop = 0;
for(i=0; i < NFrames; ){
bzero(ack,sizeof(ack));
while ((rval = recvfrom(s,ack,sizeof(ack),0,(struct sockaddr *)&client,&slen))<0){
perror("receiver recvfrom");
}
//get time
if (gettimeofday(&rectime, &zone) < 0) {
perror("getting time");
exit(1);
}
current = ack[0];
if(current == last) {
printf("Duplicate frame %d received\n", last);
continue;
}
printf("Recieved Frame #%d at time = %ld %ld\n\nContent:\n%s\n", current, rectime.tv_sec, rectime.tv_usec, ack+1);
fputs(ack+1, fp);
//creating ack
bzero(buf,sizeof(buf));
sprintf(buf, "%c%s\0", current, "ackp");
//25% chance of loss is to call random()
rnum = random();
if((rnum%4) != 0) {
// get time
if (gettimeofday(&rectime, &zone) < 0) {
perror("getting time");
exit(1);
}
if ((rval=sendto(s,buf,sizeof(buf),0,(struct sockaddr *)&client,sizeof(client))) < 0) {
perror("writing on datagram socket");
}else{
i++;
last = current;
printf("Sent Received Packet ACK for Frame %d at time = %ld %ld\n", current, rectime.tv_sec, rectime.tv_usec);
}
}else{
drop++;
}
}
printf("Total Number of dropped frames is %d\n", drop);
//get time
if (gettimeofday(&rectime, &zone) < 0) {
perror("getting time");
exit(1);
}
fclose(fp);
printf("Closing file for writing at time = %ld %ld\n", rectime.tv_sec, rectime.tv_usec);
}
//get time
if (gettimeofday(&rectime, &zone) < 0) {
perror("getting time");
exit(1);
}
printf("Closing Socked %d for File \"%s at time = %ld %ld\n", ntohs(client.sin_port), fname, rectime.tv_sec, rectime.tv_usec);
close(s);
}