如何解决服务器和客户端数据 send() 和 recv() 问题
我一直在尝试使用 C 套接字编程来编写一个客户端和服务器程序,它可以完成 2 个任务
问题 当客户端向服务器发送文件时,服务器不会显示完整的数据,看起来像 recv() 一直在等待套接字。
需要帮助
这是代码
服务器代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#define SIZE 1024
void write_file(char *filename,int sockfd){
int n;
FILE *fp ;
char buffer[SIZE] ;
fp = fopen(filename,"w");
while (1) {
n = recv(sockfd,buffer,SIZE,0);
if (n <= 0){
break;
return;
}
printf("%s",buffer) ;
fprintf(fp,"%s",buffer);
bzero(buffer,SIZE);
}
fclose(fp) ;
return;
}
int main(int argc,char *argv[]){
int portno = 7416;
int e,n,n1;
char *cmd ;
int sockfd;
struct sockaddr_in server_addr;
struct hostent *server;
char *fle = "/tmp/reposvr.";
FILE *fp;
char *num ;
if (argc < 3) {
fprintf(stderr,"usage %s hostname command \n",argv[0]);
exit(0);
}
cmd=argv[2] ;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0) {
perror("[-]Error in socket");
exit(1);
}
printf("[+]Server socket created successfully.\n");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR,no such host\n");
exit(0);
}
//server_addr.sin_family = AF_INET;
//server_addr.sin_port = port;
//server_addr.sin_addr.s_addr = inet_addr(ip);
bzero((char *) &server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(portno);
server_addr.sin_addr = *((struct in_addr *)server->h_addr);
memset(server_addr.sin_zero,'\0',sizeof server_addr.sin_zero);
e = connect(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr));
if(e == -1) {
perror("[-]Error in socket");
exit(1);
}
printf("[+]Connected to Server.\n");
n = write(sockfd,cmd,strlen(cmd));
if (n < 0)
error("ERROR writing to socket");
char *filename=NULL;
filename = (char*)malloc( 50 * sizeof(char) ) ;
strcpy(filename,fle );
n1=rand();
if (asprintf(&num,"%d",n1) == -1) {
perror("asprintf");
} else {
strcat(filename,num);
printf("%s\n",filename);
free(num);
}
printf("%s\n",filename) ;
write_file(filename,sockfd) ;
printf("[+]File data sent successfully.\n");
printf("[+]Closing the connection.\n");
close(sockfd);
return 0;
}
客户端代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#define SIZE 1024
void send_file(FILE *fp,int sockfd){
int n;
char data[SIZE] = {0};
while(fgets(data,fp) != NULL) {
if (send(sockfd,data,sizeof(data),0) == -1) {
perror("[-]Error in sending file.");
exit(1);
}
bzero(data,SIZE);
}
}
int main(){
int port = 7416;
int e,n1,n ;
FILE *fp ;
char filename[50] = "/tmp/gateway." ;
char command[50];
char *num;
FILE *pf;
char data[SIZE];
int sockfd,new_sock;
struct sockaddr_in server_addr,new_addr;
socklen_t addr_size;
char buffer[SIZE];
sockfd = socket(AF_INET,0);
if(sockfd < 0) {
perror("[-]Error in socket");
exit(1);
}
printf("[+]Server socket created successfully.\n");
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = INADDR_ANY;
e = bind(sockfd,sizeof(server_addr));
if(e < 0) {
perror("[-]Error in bind");
exit(1);
}
printf("[+]Binding successfull.\n");
if(listen(sockfd,10) == 0){
printf("[+]Listening....\n");
}else{
perror("[-]Error in listening");
exit(1);
}
addr_size = sizeof(new_addr);
while ( new_sock = accept(sockfd,(struct sockaddr*)&new_addr,&addr_size) )
{
printf("server: got connection from %s port %d\n",inet_ntoa(new_addr.sin_addr),ntohs(new_addr.sin_port));
n = read(new_sock,1024);
if (n < 0) error("ERROR reading from socket");
strcpy(command,buffer) ;
printf("%s",command) ;
pf = popen(command,"r");
bzero(data,1024);
n1=rand();
if (asprintf(&num,filename);
free(num);
}
printf("%s",filename) ;
fp=fopen(filename,"w" );
while (fgets(data,2048,pf) != NULL) {
printf("%s",data);
fprintf(fp,data) ;
}
fclose(fp) ;
fp = fopen(filename,"r");
if (fp == NULL) {
perror("[-]Error in reading file.");
exit(1);
}
send_file(fp,new_sock);
printf("[+]Data written in the file successfully.\n");
}
return 0;
}
执行输出
编辑
根据本论坛的建议,我将 SIZE 增加到 2048,发现现在返回的行数减少了,并且在 4-5 行后挂起。这很奇怪。我确定这不是因为 SIZE。
如果您看到,在客户端,我们能够成功地将所有内容写入文件。程序的第二部分是从文件中读取并将其发送到服务器。在这里,我遍历整个文件并将数据发送到服务器。数据发送循环运行良好,因为我在同一个循环中使用了 printf,我们可以看到所有数据都被打印出来。
在服务器端,我们也在循环直到读取的字节数
编辑 2 正如您在评论中看到的,已经尝试过 SIZE 、 MSG_PEEK 。还有什么建议吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。