【发布时间】:2016-03-10 13:06:45
【问题描述】:
我正在编写一些代码来为分配创建一个小型 UDS 服务器。客户端将与携带某些消息的服务器建立特定系列的连接。基本上,如果这些消息按顺序出现在我们的日志文件中,那么我们就都准备好了。但是每次运行时我的日志文件都会完全空白,我不确定我明白为什么。
这是我的代码:
// forward declarations
int error_msg( char * msg );
int usage( char name[] );
// a function to be executed by each thread
void * recv_log_msgs( void * arg );
// globals
FILE * log_fd; // opened by main() but accessible by each thread
typedef struct sockaddr SA;
void * recv_log_msgs( void * arg ) //Thread Routine
{
// loops to receive messages from a client;
// when the connection is closed by the client,
// close the socket
int clientfd = *((int *)arg);
char buffer[1500];
memset(buffer, 0, 1500);
int currentPos = 0;
int bytesRec;
int recvng = 1;
while(recvng){
bytesRec = recv(clientfd, buffer, 1500-currentPos, 0);
currentPos += bytesRec;
if(buffer[currentPos - 1] == '\n')
recvng = 0;
}
fprintf(log_fd, "LOGGER %d %s", clientfd, buffer);
close(clientfd);
return NULL;
}
int main( int argc, char * argv[] )
{
if ( argc != 3 )
return usage( argv[0] );
log_fd = fopen(argv[1], "a");
// create a server socket
// domain (i.e., family) is AF_UNIX
// type is SOCK_STREAM
socklen_t clientLength = sizeof(struct sockaddr_un);
struct sockaddr_un clientAddr;
clientAddr.sun_family = AF_UNIX;
strcpy(clientAddr.sun_path, argv[2]);
pthread_t tid;
int listenfd = socket(AF_UNIX, SOCK_STREAM, 0);
// unlink the UDS path)
unlink(argv[2]);
// bind the server socket
bind(listenfd, (SA *)&clientAddr, clientLength);
// listen
listen(listenfd, 1024);
// loop to wait for connections;
// as each connection is accepted,
// launch a new thread that calls
// recv_log_msgs(), which receives
// messages and writes them to the log file
while(1){
printf( "Waiting for a connection on UDS path %s...\n", argv[2] );
int * clientfdp = malloc(sizeof(int));
*clientfdp = accept(listenfd, (SA *) &clientAddr, &clientLength);
pthread_create(&tid, NULL, recv_log_msgs, clientfdp);
printf("%d",errno);
return 0;
}
// when the loop ends, close the listening socket
close(listenfd);
// close the log file
fclose(log_fd);
return 0;
}
写入日志发生在顶部函数recv_log_msgs。我是 C 的新手,我经常被文件处理方式的细节所困扰,或者认为内存数组的级别太高,诸如此类。鉴于我的代码,我真的不明白为什么应该写 nothing。我什至试图通过在客户端文件描述符上调用recv() 来正确“读取”数据?我是否正确使用了缓冲区?
【问题讨论】:
-
你试过使用调试器吗?
-
@MohitJain 这当然是我的第一直觉,我试过了。但是进行所有连接调用的客户端的行为是在一个可执行文件中,该可执行文件是通过分配提供给我们的。所以我不确定如何调试它。当我尝试时,它总是一直走到最后,并说它没有要显示的行号。
-
您可以尝试在 while 循环中放置一个 print 来查看 bytesRec 是否以及如何被填满。另外,你应该检查recv的返回值。
-
您的代码正在使用来自多个线程的
fprintf(log_fd, ....)。这些调用需要同步(例如,使用互斥锁)。 -
@Peter 但是这不是
join的用途吗
标签: c multithreading sockets