Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.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
c语言中的TCP套接字_C_Sockets_Tcp - Fatal编程技术网

c语言中的TCP套接字

c语言中的TCP套接字,c,sockets,tcp,C,Sockets,Tcp,我正试图为我的程序编写一个TCP套接字接口,但我发现了一个accept()错误(我想)。为此,我创建了一些简化的测试代码。 首先我做一点准备 int server_socket = 0; server_socket = socket(AF_INET, SOCK_STREAM, 0); int accepted_connection = 0; struct sockaddr_in server_address; server_address.sin_port = htons(9001); se

我正试图为我的程序编写一个TCP套接字接口,但我发现了一个accept()错误(我想)。为此,我创建了一些简化的测试代码。
首先我做一点准备

int server_socket = 0;
server_socket = socket(AF_INET, SOCK_STREAM, 0);

int accepted_connection = 0;

struct sockaddr_in server_address;
server_address.sin_port = htons(9001);
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;

struct sockaddr_in client_address;
client_address.sin_port = 0;
client_address.sin_family = AF_INET;

char * server_socket_read_buffer[100] = {0};
int server_socket_read_length = 0;
都很简单。只需分配一些变量。下一步,我绑起来听

if (bind(server_socket,(struct sockaddr *)&server_address, sizeof(server_address)) < 0)
{
    perror("Bind() on server_socket has failed\n");
}

if (listen(server_socket, 10) < 0)
{
    perror("Listen() on server_socket has failed\n");
}
if(绑定(服务器\u套接字,(结构sockaddr*)和服务器\u地址,sizeof(服务器\u地址))<0)
{
perror(“服务器_套接字上的Bind()已失败\n”);
}
如果(侦听(服务器\u套接字,10)<0)
{
perror(“服务器_套接字上的侦听()失败\n”);
}
接下来是我认为我有问题的部分

printf("Attempting accept!\n");
if (accepted_connection = accept(server_socket, (struct sockaddr *)NULL, NULL) < 0)
{
    perror("Accept failed\n");
}
sleep(10);
if (server_socket_read_length = read(accepted_connection, &server_socket_read_buffer, server_socket_read_length) < 0)
{
    perror("Read failed\n");
}
printf("Read %d bytes from socket\n", server_socket_read_length);
for (int i = 0; i<server_socket_read_length;i++)
{
    printf("%x\n",server_socket_read_buffer[i]);
}
printf(“尝试接受!\n”);
if(accepted_connection=accept(server_socket,(struct sockaddr*)NULL,NULL)<0
{
perror(“接受失败\n”);
}
睡眠(10);
如果(服务器套接字读取长度=读取(已接受的连接、服务器套接字读取缓冲区、服务器套接字读取长度)<0)
{
perror(“读取失败\n”);
}
printf(“从套接字读取%d字节”,服务器\u套接字\u读取长度);

对于(int i=0;i您正在传入
server\u socket\u read\u length=0
,这会导致最大读取长度为零。传递缓冲区大小。
server\u socket\u read\u buffer
的声明也不正确。您可能应该在堆上分配更大的缓冲区(如4KB)

还可以消除睡眠


其余部分可能正在工作,因为
nc
获得了连接,并且您能够毫无错误地接受和读取。

有几个错误:

  • INADDR\u ANY
    按主机字节顺序,需要转换为网络字节,如
    htonl(INADDR\u ANY)
    。但这并不重要,因为常量
    INADDR\u ANY
    定义为
    0

  • 这个

    char * server_socket_read_buffer[100]
    
    read(accepted_connection, &server_socket_read_buffer, server_socket_read_length)
    
    应该是

    char server_socket_read_buffer[100]
    
    read(accepted_connection, server_socket_read_buffer, sizeof server_socket_read_buffer)
    
  • 这个

    char * server_socket_read_buffer[100]
    
    read(accepted_connection, &server_socket_read_buffer, server_socket_read_length)
    
    应该是

    char server_socket_read_buffer[100]
    
    read(accepted_connection, server_socket_read_buffer, sizeof server_socket_read_buffer)
    

  • 经过更多的努力,我终于找到了我的最终答案

        if (accepted_connection = accept(server_socket, (struct sockaddr *)NULL, NULL) < 0)
        {
        //code
        }
    
    if(accepted\u connection=accept(server\u socket,(struct sockaddr*)NULL,NULL)<0)
    {
    //代码
    }
    
    无法工作。我稍后的读取被阻止,因为接受的\u连接不是有效的套接字。正在更改为

        (accepted_connection = accept(server_socket, (struct sockaddr *)NULL, NULL);
        if accepted_connection < 0)
        {
        //code
        }
    
    (accepted\u connection=accept(server\u socket,(struct sockaddr*)NULL,NULL);
    如果接受(U连接<0)
    {
    //代码
    }
    
    解决了我的问题。据我所知,文件描述符不是与if()内联创建的,从整数读取数据没有多大帮助。

    谢谢大家的输入。

    您是在需要htons()的机器上吗?这是字节交换,您很可能正在设置端口0x2923(10531)而不是0x2329(9001)。您应该始终使用
    htons()
    在设置
    sinu port
    字段时使用常量值。在little-endian机器上,字节将被反转,而在big-endian机器上,这是不可操作的。我已经做了您建议的更改,看起来程序在读取线上阻塞了。我发送了超过100字节的数据。我在上的手册页中找不到任何内容读()关于它是一个阻止功能。想一想?@Darakian为什么
    睡眠
    在那里?@DavidSchwartz它已经不存在了。睡眠在那里是为了确保我有足够的时间在另一个终端上打碎我的键盘来发送数据。@Darakian测试使用
    echo abc | nc 127.0.1 9001
    。如果不起作用,发布完整的代码。a然后我觉得自己很傻。谢谢你向我指出零长度。这个问题还没有完全解决,但这很有帮助。