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套接字上通信。我想将一块数据从客户端发送到服务器,也从服务器发送到客户端 我已经测试了最多2262个字节 我发现,当我从服务器(运行debian 7)向客户端(运行Ubuntu14.04 LTS)发送2262字节时,我能够一次接收所有字节(两者都在通过wlan进行通信的本地网络中) 但当我尝试将相同数量的字节从客户端发送到服务器时,我只能在服务器上一次性读取1448个字节(通常)和3000个字节(3000个字节是我希望从文件

我有一个服务器应用程序和一个客户端应用程序都是用c编写的。两者都在tcp套接字上通信。我想将一块数据从客户端发送到服务器,也从服务器发送到客户端

我已经测试了最多2262个字节

我发现,当我从服务器(运行debian 7)向客户端(运行Ubuntu14.04 LTS)发送2262字节时,我能够一次接收所有字节(两者都在通过wlan进行通信的本地网络中)

但当我尝试将相同数量的字节从客户端发送到服务器时,我只能在服务器上一次性读取1448个字节(通常)和3000个字节(3000个字节是我希望从文件描述符读取的最大字节数)

我还发现,如果在同一台机器上同时运行服务器和客户机应用程序,我可以同时从服务器到客户机以及从客户机到服务器发送和接收2262字节。在提出这个问题之前,我对所有案例进行了多次测试

我还参考了Beejs指南,首先我发现我必须确保一次发送的字节数准确无误。我用send和write函数检查了这一点,发现我只一次发送所有字节

我在那本书中也发现了与MTU主题相同的问题

我的第一个问题是,如果最大传输单位是原因,那么为什么我能够从服务器向客户端发送相同数量的数据,而不能从客户端接收到服务器

我的第二个问题是,如果不可能同时从服务器和客户端发送或接收数据块(肯定小于10 KB),Beej建议了一种数据封装的方法。除了Beej建议的这种方法之外,还有其他方法可以同时发送和接收数据(高达10 KB或可能超过10 KB)吗

客户端代码只是在服务器套接字上连续写入2262字节。 这是服务器代码

 #include<stdio.h>
 #include<string.h>    //strlen
 #include<stdlib.h>    //strlen
 #include<sys/socket.h>
 #include<arpa/inet.h> //inet_addr
 #include<unistd.h>    //write
 #include<pthread.h> //for threading , link with lpthread

 #define MAX_SIZE 3000 

//the thread function
void *connection_handler(void *);

int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;

//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
    printf("Could not create socket");
}
puts("Socket created");

//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 6000 );

//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
    //print the error message
    perror("bind failed. Error");
    return 1;
}
puts("bind done");

//Listen
listen(socket_desc , 3);

//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);

while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
    puts("Connection accepted");

    pthread_t sniffer_thread;
    new_sock = malloc(1);
    *new_sock = client_sock;

    if( pthread_create( &sniffer_thread , NULL ,  connection_handler , (void*) new_sock) < 0)
    {
        perror("could not create thread");
        return 1;
    }

    //Now join the thread , so that we dont terminate before the thread
    //pthread_join( sniffer_thread , NULL);
    puts("Handler assigned");
}

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

return 0;
}

/*
 * This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size, i;
uint8_t message[MAX_SIZE];

//Receive a message from client
while( (read_size = read(sock , message , sizeof(message))) > 0 )
{
i = 0;
printf("bytes read- %d\n", read_size);

}

if(read_size == 0)
{
    puts("Client disconnected");
    fflush(stdout);
}
else if(read_size == -1)
{
    perror("recv failed");
}

//Free the socket pointer
free(socket_desc);

return 0;
}
#包括
#包括//strlen
#包括//strlen
#包括
#包括//inet\u addr
#包括//写入
#包括//对于线程,使用lpthread链接
#定义最大尺寸3000
//线程函数
void*连接处理程序(void*);
int main(int argc,char*argv[])
{
int socket_desc,client_sock,c,*new_sock;
服务器、客户端中的结构sockaddr_;
//创建套接字
socket\u desc=socket(AF\u INET,SOCK\u STREAM,0);
如果(套接字描述==-1)
{
printf(“无法创建套接字”);
}
放置(“已创建套接字”);
//在结构中准备sockaddr_
server.sinu family=AF\u INET;
server.sin\u addr.s\u addr=INADDR\u ANY;
server.sin_port=htons(6000);
//束缚
if(绑定(socket_desc,(struct sockaddr*)&server,sizeof(server))<0
{
//打印错误消息
perror(“绑定失败。错误”);
返回1;
}
看跌期权(“绑定完成”);
//听
听(插座描述,3);
//接受和传入连接
puts(“等待传入连接…”);
c=sizeof(结构sockaddr_in);
而((client_sock=accept(socket_desc,(struct sockaddr*)和client,(socklen_t*)和c)))
{
看跌期权(“已接受连接”);
pthread\u t sniffer\u线程;
新_sock=malloc(1);
*新建_sock=客户端_sock;
if(pthread_create(&sniffer_thread,NULL,connection_handler,(void*)new_sock)<0)
{
perror(“无法创建线程”);
返回1;
}
//现在加入线程,这样我们就不会在线程之前终止
//pthread_join(嗅探器_线程,NULL);
看跌期权(“指定的处理人”);
}
如果(客户_sock<0)
{
perror(“接受失败”);
返回1;
}
返回0;
}
/*
*这将处理每个客户端的连接
* */
void*连接处理程序(void*套接字描述)
{
//获取套接字描述符
int sock=*(int*)插座描述;
int read_size,i;
uint8_t消息[最大大小];
//从客户端接收消息
而((read_size=read(sock,message,sizeof(message)))>0)
{
i=0;
printf(“读取字节-%d\n”,读取大小);
}
如果(读取大小==0)
{
出售(“客户断开连接”);
fflush(stdout);
}
else if(读取大小==-1)
{
perror(“recv失败”);
}
//释放套接字指针
自由(插座描述);
返回0;
}
引用

返回值

成功时,返回读取的字节数(零表示结束) ,文件位置将按此数字前进。事实并非如此 如果此数字小于请求的字节数,则为错误; 例如,这可能是因为实际可用的字节更少 现在(可能是因为我们快到文件末尾了,或者是因为我们 正在从管道或终端读取),或者因为read()是 被信号打断


所以阅读并不像你期望的那样有效。它不保证它会在一次通话中返回您请求的金额。您指定的金额只是您收到的实际数据的上限。

忘记所有MTU。TCP存在的真正原因是保护您(用户)免受低级UDP内容的影响,包括MTU。TCP是一种面向流的协议。你在一边倒字节,在另一边读字节。大小不重要。不管你在一边倒了多少,你永远不会知道在任何给定的时间里你能在接受者一边得到多少。使用TCP的唯一明智的方法是读取流,而不期望通过每个
recv()
调用传递任何特定数量的字节,并处理您得到的任何数据。

您可能会注意到,服务器最终接收到从客户端发送的所有数据,无论调用了多少次
read
new\u sock=malloc(1)*新建_sock=客户端_sock不!这是巴亚德!你在读哪本书?是的,帕布。你说的对@Seb这里有什么问题?谢谢您的回复。@EdgeGoldberg问题是,您正在分配一个字节,并将该字节视为一个
int
(很可能不止一个字节)。我想你是想写一些东西,比如
new\u sock=malloc(sizeof*new\u sock)。。。而且是p