Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TCP客户端/服务器打印额外字符串_C_Sockets_Tcp - Fatal编程技术网

TCP客户端/服务器打印额外字符串

TCP客户端/服务器打印额外字符串,c,sockets,tcp,C,Sockets,Tcp,我正在尝试制作一个带有服务器的程序,多个客户端可以通过预定义的端口号连接到该服务器。顺便说一下,这是C中的TCP。我有以下服务器代码: 服务器代码: #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h>

我正在尝试制作一个带有服务器的程序,多个客户端可以通过预定义的端口号连接到该服务器。顺便说一下,这是C中的TCP。我有以下
服务器
代码:

服务器代码:

#include <stdio.h>
#include <string.h>    
#include <stdlib.h>    
#include <sys/socket.h>
#include <arpa/inet.h> 
#include <unistd.h>    
#include <pthread.h> 

void *connection_handler(void *);

int main(int argc , char *argv[])
{
    int listenfd , connfd , c , *new_sock;
    struct sockaddr_in servaddr , cliaddr;
    listenfd = socket(PF_INET , SOCK_STREAM , 0);
    if (listenfd == -1)
        puts("SOCKET CREATION ERROR!");
        puts("Socket created");

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(54321);
    bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr) );
    listen(listenfd,2);;
    c = sizeof(struct sockaddr_in);

    while( (connfd = accept(listenfd, (struct sockaddr *)&cliaddr, (socklen_t*)&c)) ){
            puts("Connection accepted");
        pthread_t sniffer_thread;
            new_sock = malloc(1);
            *new_sock = connfd;

            if( pthread_create( &sniffer_thread , NULL ,  connection_handler , (void*) new_sock) < 0)
        {
                perror("Thread Error Connection");
            return 1;
            }
            puts("Handler assigned");
        }

    if (connfd < 0)
    {
            perror("accept failed");
            return 1;
    }
        return 0;
}


void *connection_handler(void *socket_desc)
{
    int sock = *(int*)socket_desc;
    int read_size;
    char client_message[51]="";

    while( (read_size = recv(sock , client_message , 50, 0)) > 0 )
    {
            printf("%s",client_message);
        }

        if(read_size == 0)
        {
            puts("Client disconnected");
            fflush(stdout);
        }
        free(socket_desc);
    return 0;
}
我在客户端输入了以下字符串:

Hello There!
What could be the problem?
I don't know?
Hey!

问题是当我输入第三个字符串时,输出是第三个字符串,第二个字符串的某些部分仍然出现。有什么问题吗?谢谢

C字符串以null结尾。您没有发送将在接收缓冲区中终止字符串的零字节,因此printf将打印它找到的所有字符,直到到达某个零字节。strlen以字符数返回字符串的长度,但不计算末尾的零字节

尝试更改客户端中的行:

sendto(sockfd,mesg,strlen(mesg),0,(const struct sockaddr *)&servaddr,len);
进入:

  • TCP是面向流的

  • 您不能期望
    write()
    写入的数据与您让它写入的数据一样多,也不能期望
    read()
    读取的数据与您让它读取的数据一样多

  • 这两者加在一起意味着要通过套接字传输N个字节,对
    read()
    的调用数不一定需要与对
    write()
    的调用数相匹配

    根据这个结论,读者唯一能知道的就是它从被创造的那一刻起读了多少

    读写器之间只有两个同步点,即创建和关闭连接。可以调用会话的时间段

    因此,如果一个人想在一次会话期间传输多个大小不同的数据块,而读卡器不知道这些数据块的大小,那么他需要在会话期间建立额外的同步点,使读卡器检测到已接收到完整的数据块

    这样做就是实现某种协议

    protcol的样子有无限的可能性。协议的详细设计取决于应用程序应涵盖的用例

    假设只传输文本数据,一个简单的协议可以是通过
    \n
    终止每个数据块

    写入程序循环
    write()
    ,直到发送所有数据,最后发送
    \n


    阅读器在
    read()
    中循环,直到收到
    \n
    为止。

    上面说我可以在3分钟内接受你的答案。就等着吧,不过非常感谢<代码>新_sock=malloc(1)*新袜子=connfd:您必须是C语言的新手。
    Hello There!
    What could be the problem?
    I don't know?
    Hey!
    
    sendto(sockfd,mesg,strlen(mesg),0,(const struct sockaddr *)&servaddr,len);
    
    sendto(sockfd,mesg,1+strlen(mesg),0,(const struct sockaddr *)&servaddr,len);