我正在学习C语言的套接字编程,我们必须编写一个TCP客户端/服务器,其中客户端将文件逐行发送到服务器,以便它可以执行以下两项操作之一(min,avg)它将输出发送回客户端。
输入文件遵循以下格式:
AVG 1 2 3 4 5 6
MIN 1 2 3 4 5 -8
MIN 1 2 3 0 5 6
问题是服务器仅读取一行并进行计算,并且出于某种原因,客户端的输出后面还会跟有零!
服务器代码:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#define MAXLINE 4096
double average(int num[],int iterations); //to find the average value
int minimun(int num[],int iterations); //to find the minimum value
double get_op(char b[],int op); //to distinguish between the operations
int startswith(const char *pre, const char *str); //to find if the operatioon is valid only min or avg
int main(int argc, char *argv[]){
if(argc != 2){ //recieves portnumber
printf("Missing port number please try again.\n");
return 1;
}
int listenfd = 0, connfd = 0 , line = 0;
char SENDBUFFER[2048] = "\0";
char recvBuff[2048] = "\0";
struct sockaddr_in serv_addr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(recvBuff, '0', sizeof(recvBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_port = htons(atoi(argv[1]));
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 4); //listens to 4 clients max
while(1)
{
socklen_t szaddr = sizeof(serv_addr);
connfd=accept(listenfd,(struct sockaddr*)&serv_addr,&szaddr);
int pid;
if( (pid = fork()) == 0 ) { // Child
close(listenfd);//close listening sock
printf("Connected...");
while(1){
read(connfd,recvBuff,sizeof(recvBuff)-1);
int op;
line++;
double ans;
if(startswith("AVG ",recvBuff)){
op = 1;
ans = get_op(recvBuff,1);
sprintf(SENDBUFFER," %f",ans);
strcat(recvBuff," = ");
strcat(recvBuff,SENDBUFFER);
write(connfd, recvBuff, strlen(recvBuff));
}
if(startswith("MIN ",recvBuff)){
op = 2;
ans = get_op(recvBuff,2);
sprintf(SENDBUFFER," %f",ans);
strcat(recvBuff," = ");
strcat(recvBuff,SENDBUFFER);
write(connfd, recvBuff, strlen(recvBuff));
}
else{
memset(SENDBUFFER, '0', sizeof(SENDBUFFER));
strcat(SENDBUFFER,"Unsupported Operation on Line #");
char *str = "";
sprintf(str, "%d", line);
strcat(SENDBUFFER,str);
write(connfd, SENDBUFFER, strlen(SENDBUFFER));
}
}
close(connfd);
sleep(1);// child terminates
}else {// Parent
close(connfd); // close connected socket
}
}
return 0;
}
int minimun(int num[],int iterations){
int c;
int min = num[0];
for (c = 0;c<iterations; c++){
if (num[c] <= min){
min = num[c];
}
}
return min;
}
int startswith(const char *pre, const char *str){
char cp;
char cs;
if (!*pre)
return 1;
while ((cp = *pre++) && (cs = *str++)){
if (cp != cs)
return 0;
}
if (!cs)
return 0;
return 1;
}
double average(int num[],int iterations){
int sum = 0,c = 0;
double avg = 0;
int i;
for(i = 0;i<iterations;i++){
sum=sum+num[i];
}
avg=(double)sum/iterations;
return avg;
}
double get_op(char b[],int op){
int arr[2048], idx=0, d, l=0;
char *p; int counter = 0;
for (p = b; *p != 0; p+=l) {
l = 1;
if (isdigit(*p)){
sscanf(p, "%d%n", &d, &l);
arr[idx++] = d;
}
}
if(op==1)//avg
return average(arr,idx);
else //min
return (double)(minimun(arr,idx));
}
这是客户端代码:
/* Client Code - Client.c */
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#define MAXLINE 4096
#define filename "path to file"
int main(int argc,char *argv[])
{
char SENDBUFFER [MAXLINE] = "\0";
char recvBuff [MAXLINE] = "\0";
struct sockaddr_in serv_addr;
//int len;
int sockfd ;
if(argc<5){
printf("usage:serv_IP_addr, serv_port,num_of_microsec,nam_of_fil to read the input from\n");
exit(0);}
memset(SENDBUFFER, '0', sizeof(SENDBUFFER));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0))< 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(atoi(argv[2])); // port
serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
/* Attempt a connection */
if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))<0){
printf("\n Error : Connect Failed \n");
return 1;
}
FILE *file; //file to read from
file = fopen("file path", "r"); //path to file
if (file == NULL){
printf("File not found!\n");
return 1;
}
printf("Found file %s\n", filename);
printf("Sending the file now\n");
//write function
while(fgets(SENDBUFFER, MAXLINE,file)!=NULL){
write(sockfd, SENDBUFFER, sizeof(SENDBUFFER)-1);
}
//read function
memset(recvBuff,'0',sizeof(recvBuff));
int n ;
while((n=read(sockfd,recvBuff,sizeof(recvBuff)-1))> 0){
if(fputs(recvBuff,stdout)==EOF){
printf("\n Error : nothing recieved\n");
}
}
printf("\nDone Sending the File!\n");
printf("Now Closing Connection.\n");
fclose(file);
close(sockfd);
return 0;
}
P.S:我添加了fork(),因为我试图使服务器最多容纳4个客户端,而其他服务器仍在等待,但仍未完成。