【问题标题】:TCP Server-Client disconnects after a single transmission [closed]TCP Server-Client 在单次传输后断开连接[关闭]
【发布时间】:2020-05-26 17:49:59
【问题描述】:

我正在为学校开发一个服务器-客户端程序,并为 TCP 连接使用给定的代码。 客户端:

void func(int sockfd) 
{ 
char entryArr[MAXSIZE][MAXLEN];
int n,c;
int i = 0;
char entry;
char iEntry[1];
char id[6];
char fname[5];
char lname[5];
char score[4];
for (;;) { 
    bzero(id, sizeof(id));
    bzero(fname, sizeof(fname));
    bzero(lname, sizeof(lname));
    bzero(score, sizeof(score));    
    printf("[1] Add a Student \n");     //Menu
    printf("[2] Display ID \n");
    printf("[3] Display Score \n");
    printf("[4] Display All \n");
    printf("[5] Delete an Entry \n");
    printf("[6] Exit \n");
    printf("Please Select from the Menu: ");  //get menu selection
    scanf("%1s", iEntry);   //read entry

    if (iEntry[0] == '1') //if entry = 1
    {
        getchar();
        printf("\n------Add a New Student------  \n"); 
        printf("\n6-Digit ID: "); 
        scanf("%6s", id);           //read 6 digit id

        while ( (c = getchar()) != '\n' && c != EOF );
        printf("Student's First Name: "); 
        scanf("%5s", fname);                //read first namae

        while ( (c = getchar()) != '\n' && c != EOF );

        printf("Student's Last Name: "); 
        scanf("%5s", lname);                //read last name
        while ( (c = getchar()) != '\n' && c != EOF );
        printf("Student's Score: "); 
        scanf("%3s", score);                //read score

        while ( (c = getchar()) != '\n' && c != EOF );

        write(sockfd, iEntry, sizeof(iEntry)); //write entry number
        write(sockfd, id, sizeof(id));          //write id
        write(sockfd, fname, sizeof(fname));    //write fname
        write(sockfd, lname, sizeof(lname));    //write lname
        write(sockfd, score, sizeof(score));    //write score
        printf("\n------Student Added------\n");
        i++;

    }
int main()
{
    int sockfd;
    struct sockaddr_in serverAddr;
    socklen_t addr_size;

    sockfd = socket(PF_INET, SOCK_STREAM, 0);
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(7891);
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);  

    addr_size = sizeof serverAddr;
    connect(sockfd, (struct sockaddr *) &serverAddr, addr_size);

    func(sockfd);

    close(sockfd); 
}

服务器端:

void func(int sockfd) 
{ 

int i = 0;
char idArr[MAXSIZE][MAXLEN];
char fnameArr[MAXSIZE][MAXLEN];
char lnameArr[MAXSIZE][MAXLEN];
char scoreArr[MAXSIZE][MAXLEN];
char entryArr[MAXSIZE][MAXLEN];
char iEntry[1];

char id[6];
char fname[5];
char lname[5]; 
char score[3]; 
int n,c;
char entry;
// infinite loop for chat 
for (;;) {
    printf("HERE6\n");
    bzero(iEntry, sizeof(iEntry));
    bzero(id, sizeof(id));
    bzero(fname, sizeof(fname));
    bzero(lname, sizeof(lname));
    bzero(score, sizeof(score));
    read(sockfd, iEntry, sizeof(iEntry));
    strcpy(entryArr[0], iEntry);
    if (iEntry[0] == '1')
    {
        read(sockfd, id, sizeof(id));

        read(sockfd, fname, sizeof(fname));
        read(sockfd, lname, sizeof(lname));
        read(sockfd, score, sizeof(score));
        printf("HERE5\n");
        strcpy(idArr[i], id);
        strcpy(fnameArr[i], fname);
        strcpy(lnameArr[i], lname);
        strcpy(scoreArr[i], score);

        printf("Student Added.\n");
        i++;
}
int main()
{
int sockfd, connfd;
struct sockaddr_in serverAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size;

sockfd = socket(PF_INET, SOCK_STREAM, 0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(7891);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);  

bind(sockfd, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
if(listen(sockfd,5)==0)
    printf("Listening\n");
else
    printf("Error\n");
addr_size = sizeof serverStorage;
connfd = accept(sockfd, (struct sockaddr *) &serverStorage, &addr_size);

func(connfd); 
close(sockfd); 
}

在我的 func() 函数中,我正在运行一个带有选项的菜单。该程序在使用 PuTTy(即 eros.tx.state.edu)在同一终端上运行时按预期工作。 当我在两个不同的终端(在同一台机器上)上运行时,程序可以运行,但一旦到达第一个 write() 就会退出。

知道为什么会这样吗? 抱歉,我试图将其保持在最低限度。

【问题讨论】:

  • “忽略 func() 函数中的循环”。什么循环?您没有显示func 代码,因此我们很难猜测为什么会退出看不见的循环。请根据 Stack Overflow 调试问题提供minimal verifiable example
  • “当我连接到两个不同的服务器(在同一台机器上)”。您是否运行相同的服务器代码?您不能将两个进程绑定到同一个端口号,这样就不起作用了。
  • 双方都在发送,也不在接收。没有多大意义。代码中几乎完全没有错误检查。
  • 如果它运行良好,那不是意味着它应该在所有情况下都运行吗?既然没有,那岂不是没有你想的那么好?根据定义,您不知道问题出在哪里,经验表明,调试我们无法自己运行的不完整代码是徒劳的。因此需要一个最小的可验证示例。
  • 那么可能应该回答我的第二个问题。“不同的服务器”是什么意思?每个端口只能绑定到一个服务器(例如,您不能在同一台机器上使用端口 80 运行两个 Web 服务器)

标签: c tcp client-server


【解决方案1】:
char iEntry[1];

好的,iEntry 包含一个字符。

read(sockfd, iEntry, sizeof(iEntry));
strcpy(entryArr[0], iEntry);

为什么要将iEntry 传递给strcpy?这是一个单一的字符。你怎么期望strcpy 知道它应该只复制一个字符?

为什么不直接测试iEntry[0]?为什么iEntry 还是一个数组?

您的代码忽略了read 的返回值。您至少需要通过编写某种“读取所有”函数来处理短读取,该函数精确读取指定的字节数。

【讨论】:

  • 即使我将其注释掉,结果也是一样的。代码在到达客户端的第一个 write() 时立即退出。
  • 您修复了serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 吗?您是否在 connectbindlisten 等函数中添加了错误检查?
  • 这是一个给定的代码。我没有改变它。服务器保持在“监听”状态,客户端在尝试 write() 时存在
  • 如果没有错误检查,您将无法弄清楚为什么它不起作用。函数返回值是有原因的。
猜你喜欢
  • 2011-06-29
  • 2021-05-11
  • 1970-01-01
  • 1970-01-01
  • 2015-05-18
  • 2014-05-16
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多