gpt4 book ai didi

c - 在 C 的 POSIX 线程中使用时,recvfrom() 给出错误的文件描述符错误

转载 作者:行者123 更新时间:2023-11-30 15:28:41 26 4
gpt4 key购买 nike

我正在实现一个迷你 youtube 类型的套接字接口(interface)。当从线程 main_server 中的子服务器接收数据时,问题就出现了,该线程可以轻松处理多个子服务器。如果我在 main 中创建线程后通过 pthread_join 加入线程,则线程调用成功并且从子服务器接收数据,但这在技术上破坏了创建多线程子服务器环境的全部意义。如果我不加入线程,则会出现以下错误:

Alis-MacBook-Pro:Desktop aliabbasjaffri$ gcc main_server.c -w -lpthread -o s
Alis-MacBook-Pro:Desktop aliabbasjaffri$ ./s

bind = 0 SFD: 3
Thread Created!!!
SFD: 3 Inside thread function!

recvfrom(): Bad file descriptor
ERROR RECEIVING STUFF!!!!!!!!!
Received stuff:
SubServerNum: -48
Address:
Bus error: 10

当我通过pthread_join加入线程时,执行成功,并且成功从子服务器接收到数据。这是终端上显示的内容。

Alis-MacBook-Pro:Desktop aliabbasjaffri$ gcc main_server.c -w -lpthread -o s
Alis-MacBook-Pro:Desktop aliabbasjaffri$ ./s
bind = 0 SFD: 3
Thread Created!!!
SFD: 3 Inside thread function!

Received stuff: 1,0.0.0.0,8888,hello.mp4,10.0
SubServerNum: 1
Address: 0.0.0.0
Port: 8888
Video Name: hello.mp4
Video Size: 10.000000



Received stuff: 1,0.0.0.0,8888,world.mp4,20.0
SubServerNum: 1
Address: 0.0.0.0
Port: 8888
Video Name: world.mp4
Video Size: 20.000000



Received stuff: end
Exiting the thread!

我的主服务器代码如下。

#include <netinet/in.h> 
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <fcntl.h>

//////////////////////////////////////////////~~GLOBAL DECLARATIONS~~///////////////////////////

const int numberOfThreads = 1; //Number of threads to get data from subservers!
const int sizeOfVideosStruct = 6;

int PORT = 8889; //port number

struct sockaddr_in server , client;
socklen_t len = sizeof( client );

struct videosList
{
int serverNumber;

char address[30];
int port;

char movieName[50];
int movieSize;
};

struct videosList videos[ sizeOfVideosStruct ]; //movies from subservers

//////////////////////////////////////////////////////////////////////////////////////////////////


void subserverReplyParserAndEntryManager( char line[] )
{
int subServerNumber = 0 , i = 0 , j = 0;
int port = 0;
float size = 0;
char address[20] = "" , RPort[5] = "" , videoName[40] = "" , RSize[6] = "";

subServerNumber = line[0];
subServerNumber -= 48;

printf("SubServerNum: %d\n", subServerNumber );

for( i = 2; ; )
{
if( line[i] == ',' )
{
break;
}

address[j++] = line[i++];
}

printf("Address: %s\n", address );

i++;
j = 0;

for( ; ; )
{
if( line[i] == ',' )
{
break;
}

RPort[j++] = line[i++];
}

port = atoi(RPort);

printf("Port: %d\n", port );

i++;
j = 0;

for( ; ; )
{
if( line[i] == ',' )
{
break;
}

videoName[j++] = line[i++];
}

printf("Video Name: %s\n", videoName );

i++;
j = 0;

for( ; ; )
{
if( line[i] == '\0' )
{
break;
}

RSize[j++] = line[i++];
}

size = atoi(RSize);

printf("Video Size: %f\n\n\n", size );
}

void * subserverThreadFunction( void * threadArgument )
{
char data[1000];

int sfd = ( int ) threadArgument;

printf("SFD: %d Inside thread function!\n" , sfd);

while( strcmp( data , "end" ) != 0 )
{
if( recvfrom( sfd , data , 1000 , 0 , (struct sockaddr *)&client , &len ) == -1 )
{
perror("recvfrom()");
printf("ERROR RECEIVING STUFF!!!!!!!!!");
}

printf("\nReceived stuff: %s\n" , data);

if( strcmp( data , "end" ) == 0 )
{
break;
}

subserverReplyParserAndEntryManager( data );
}

printf("Exiting the thread!");

pthread_exit(NULL);
}


void sendDataToClient()
{

}

int main()
{
pthread_t thread;
char buffer1[1024] = "";

int num = 0 , rc = 0;

int sfd = socket( AF_INET , SOCK_DGRAM , 0);

bzero( &server , sizeof(server) );

server.sin_family = AF_INET;
server.sin_port = htons( PORT );
server.sin_addr.s_addr = inet_addr("0.0.0.0");

printf( "bind = %d SFD: %d\n" , bind( sfd , (struct sockaddr *)&server , sizeof(server) ) , sfd );

////////////////////////////////

for( num = 0; num < numberOfThreads; num++ )
{
printf("Thread Created!!!\n");
rc = pthread_create( &thread , NULL, subserverThreadFunction, (void *) sfd );

pthread_join( thread , NULL );

if (rc)
{
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}

///////////////////////////////////


///////////////////////////////////

//printf( "Please enter the query from the client!\n");

/*

recvfrom( sfd , buffer1 , 1024 , 0 , (struct sockaddr *)&client , &l );
printf( "Message from client: %s\n" , buffer1);

printf( "Message to client: " );

for( int i = 0; i < 5; i++ )
{
if( strcmp( listOfVideos[i] , buffer1 ) == 0 )
{
printf( "\nOne match found: %s" , listOfVideos[i] );
sendto( sfd , listOfVideos[i] , strlen( listOfVideos[i] ) , 0 , (struct sockaddr *)&client , l );
}
}
sendto( sfd , "" , strlen( "" ) , 0 , (struct sockaddr *)&client , l );

*/

///////////////////////////////////

//sendto( sfd , buffer2 , strlen(buffer2) , 0 , (struct sockaddr *)&client , l );

close(sfd);

printf( "\n" );

pthread_exit(NULL);

return 0;
}

我的子服务器代码如下:

#include <netinet/in.h> 
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <fcntl.h>

int PORT = 8889;

int main()
{
int sfd = 0,l = 0, breaker = 0 , i = 0;

int number = 1;

char *buffer1[2] , end[4] = "end";

buffer1[0] = "1,0.0.0.0,8888,hello.mp4,10.0";
buffer1[1] = "1,0.0.0.0,8888,world.mp4,20.0";

struct sockaddr_in ser;

sfd = socket( AF_INET , SOCK_DGRAM , 0 );

bzero( &ser , sizeof(ser) );

ser.sin_family = AF_INET;
ser.sin_port = htons( PORT );

inet_aton("0.0.0.0" , &ser.sin_addr);

while( breaker != 2 )
{
sendto( sfd , buffer1[i] , strlen( buffer1[i] ) , 0 , (struct sockaddr *)&ser , sizeof(ser) );

printf("\nString sent to server: %d" , i );

breaker++;
i++;
}

sendto( sfd , end , sizeof(end) + 1 , 0 , (struct sockaddr *)&ser , sizeof(ser) );

printf("\nData sent successful!");

close(sfd);

printf( "\n" );

return 0;
}

我已经被困在这个问题上很长一段时间了,我似乎无法弄清楚问题出在哪里。任何帮助将不胜感激!

最佳答案

如果没有 pthread_join(),您的服务器例程将创建新线程,传入套接字文件描述符,然后立即继续并关闭新创建的套接字。

如果您创建多个线程,那么您需要执行一些操作,例如将线程 ID 存储在数组中,然后在创建它们的循环之外将它们连接起来。

最后一件事 - 您真的打算将相同的套接字描述符传递给每个线程吗?如果可以的话,我建议您获取《Unix 网络编程,第 1 卷:套接字网络 API(第 3 版)》的副本,其中将提供有关如何创建客户端/服务器应用程序的大量信息。

关于c - 在 C 的 POSIX 线程中使用时,recvfrom() 给出错误的文件描述符错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26489057/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com