C 如何使用套接字强制发送数据

C 如何使用套接字强制发送数据,c,sockets,buffer,C,Sockets,Buffer,我正在通过C中的套接字构建客户机/服务器分布式应用程序。 这是我的服务器: #include <stdio.h> #include <sys/socket.h> #include <netdb.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #include <netinet/tcp.h

我正在通过C中的套接字构建客户机/服务器分布式应用程序。
这是我的服务器:

#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <netinet/tcp.h>

#define LEN 20

int main(void) {
  int err, nread, status, optval=1;
  int sd, ns;
  char category[LEN];
  struct addrinfo hints, *res;

  memset(&hints, 0, sizeof(hints));
  hints.ai_flags = AI_PASSIVE;
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;

  if((err = getaddrinfo(NULL, "50000", &hints, &res)) != 0) {
    printf("%s", gai_strerror(err));
    exit(-1);
  }

  if((sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) {
    printf("Error in Socket Server\n");
    exit(-1);
  }

  setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

  if(bind(sd, res->ai_addr, res->ai_addrlen) != 0) {
    printf("Error in bind\n");
    exit(-1);
  }

  freeaddrinfo(res);

  if(listen(sd, 5) != 0) {
    printf("Error in listen\n");
    exit(-1);
  }

  for(;;) {
        if((ns = accept(sd, NULL, NULL)) < 0) {
        printf("Error in accept\n");
        exit(-10);
    }

    /* I tried with this: setsockopt(ns, IPPROTO_TCP, TCP_NODELAY, (char*)&optval, sizeof(int));  
    but it didn't work out */

    while((nread = read(ns, category, LEN)) > 0){

        if(category[nread-1]=='\n') {
            category[nread-1]='\0';
        }

        if(fork()==0) {

        close(1);
        dup(ns);
        close(ns);
        execlp("grep", "grep", category, "conto_corrente.txt", (char *)0);
        perror("Error in fork\n");
        exit(-100);
        }
        wait(&status);
      }

      close(ns);
  }
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义LEN 20
内部主(空){
int err、nread、status、optval=1;
int-sd,ns;
字符类别[LEN];
结构addrinfo提示,*res;
memset(&hints,0,sizeof(hints));
hits.ai_flags=ai_被动;
hits.ai_family=AF_unsec;
hits.ai_socktype=SOCK_流;
if((err=getaddrinfo(NULL,“50000”&提示和res))!=0){
printf(“%s”,gai_strerror(err));
出口(-1);
}
如果((sd=socket(res->ai_系列,res->ai_socktype,res->ai_协议))<0){
printf(“套接字服务器中的错误\n”);
出口(-1);
}
setsockopt(sd、SOL_插槽、SO_REUSEADDR和optval、sizeof(optval));
如果(绑定(sd,res->ai_addr,res->ai_addrlen)!=0){
printf(“绑定错误”\n);
出口(-1);
}
freeaddrinfo(res);
如果(听(sd,5)!=0){
printf(“侦听中出错\n”);
出口(-1);
}
对于(;;){
如果((ns=accept(sd,NULL,NULL))<0){
printf(“接受错误”);
出口(-10);
}
/*我试过这样做:setsockopt(ns,IPPROTO_TCP,TCP_NODELAY,(char*)和optval,sizeof(int));
但是没有成功*/
而((nread=读取(ns,类别,LEN))>0){
如果(类别[nread-1]='\n'){
类别[nread-1]='\0';
}
如果(fork()==0){
关闭(1);
dup(ns);
关闭(ns);
execlp(“grep”,“grep”,类别,“conto_corrente.txt”,(char*)0);
perror(“fork中的错误”);
出口(-100);
}
等待(&状态);
}
关闭(ns);
}
}
这是我的客户:

#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv) {
int err, nread;
int sd;
char category[20];
char buff[1024];
struct addrinfo hints, *res, *ptr;

if(argc!=3) {
    printf("Error in number of parameters\n");
    exit(-1);
}

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;

if((err = getaddrinfo(argv[1], argv[2], &hints, &res)) != 0) {
    printf("%s\n", gai_strerror(err));
    exit(-1);
}

for(ptr = res; ptr != NULL; ptr=ptr->ai_next) {
    if((sd = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol)) < 0) {continue;}

    if((connect(sd, ptr->ai_addr, ptr->ai_addrlen)) == 0) {
        break;
    }
}

if(ptr==NULL) {
    printf("Error in connection\n");
    exit(-1);
}

freeaddrinfo(res);

printf("Category: ");
scanf("%s", category);

while(strcmp(category, "fine") != 0) {
    write(sd, category, strlen(category)+1);

    while((nread = read(sd, buff, 1024)) > 0) {
        printf("%s", buff);
    }

    printf("Category: ");
    scanf("%s", category);
}
close(sd);

return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符**argv){
int err,nread;
国际标准差;
炭类[20];
字符buff[1024];
结构addrinfo提示,*res,*ptr;
如果(argc!=3){
printf(“参数数量错误\n”);
出口(-1);
}
memset(&hints,0,sizeof(hints));
hits.ai_family=AF_unsec;
hits.ai_socktype=SOCK_流;
if((err=getaddrinfo(argv[1]、argv[2]、&提示和res))!=0){
printf(“%s\n”,gai_strerror(err));
出口(-1);
}
对于(ptr=res;ptr!=NULL;ptr=ptr->ai_next){
如果((sd=socket(ptr->ai_系列,ptr->ai_socktype,ptr->ai_协议))<0){continue;}
如果((连接(sd,ptr->ai_addr,ptr->ai_addrlen))==0){
打破
}
}
如果(ptr==NULL){
printf(“连接错误”);
出口(-1);
}
freeaddrinfo(res);
printf(“类别:”);
scanf(“%s”,类别);
而(strcmp(类别,“罚款”)!=0){
写作(sd,分类,斯特伦(分类)+1);
而((nread=read(sd,buff,1024))>0){
printf(“%s”,浅黄色);
}
printf(“类别:”);
scanf(“%s”,类别);
}
关闭(sd);
返回0;
}
程序应该从用户那里获取一个输入(一个字符串),并将其发送到服务器,服务器必须扫描文件并选择包含该字符串的所有行


我认为缓冲区中存在一个问题,因为当用户输入字符串时,客户端停止,看起来好像在等待什么,事实上,如果我杀死服务器,客户端就会显示它读取的内容。怎么样?

去掉循环中的第二次读取。对不起,我的疏忽……但是在第一次从套接字读取后,通过“printf”(“%s”,nread,buff)打印读取后,它会停止“buff”的内容;'您还犯了一个常见的错误,即假设发送端的一次写入等于接收端的一次读取。事实并非如此,这是一个字节流协议。你必须循环直到你得到你想要的。然后继续。目前,您的客户机正在尝试读取套接字,直到流结束。