今天在调BUG发现一个很奇怪的问题,描述如下:
void file_do_transmit_firmware(evutil_socket_t fd, short event, void *arg)
{
struct sockaddr_in peeraddr;
pthread_t thread_id;
socklen_t socklen;
int s, clientfd;
clientfd = accept(fd, (struct sockaddr*)&peeraddr, &socklen);
if (clientfd < 0) {
log_debug("file: accept failed: %s\n", strerror(errno));
return;
}
if (CurrConnected >= MaxConnection || !peer_find(peeraddr.sin_addr)) {
log_debug("file: current connect peer[%d] lager then MaxConnection[%d], or there is no client %s, fd: %d\n",\
CurrConnected, MaxConnection, system_inet_ntoa(peeraddr.sin_addr), clientfd);
close(clientfd);
return ;
}
CurrConnected++;
peer_unset_flag(peeraddr.sin_addr, BIN_SENDED);
log_debug("file: accept non-dr %s, cur num:%d, fd: %d\n", system_inet_ntoa(peeraddr.sin_addr), CurrConnected, clientfd);
s = pthread_create(&thread_id, NULL, (void *)file_transmit_firmware_thread, (void *)clientfd);
if (s != 0) {
log_debug("pthread create failed: %s\n", strerror(errno));
if (CurrConnected > 0) CurrConnected--;
close(clientfd);
system_track_exit(EXIT_THREAD);
}
return;
}
void *file_transmit_firmware_thread(void *arg)
{
struct sockaddr_in peeraddr;
struct thread_args *args;
unsigned int peerlen = sizeof(struct sockaddr_in);
static struct stat file_info;
int datafd = -1;
int fd = (int)arg;
int rc;
ev_uint64_t msg = pthread_self();
rc = getpeername (fd, (struct sockaddr *)&peeraddr, &peerlen);
if (rc < 0) {
log_debug("getpeername failed: %s\n", strerror(errno));
pthread_detach(pthread_self());/* 自生自灭 */
return NULL;
}
log_debug("file: start to transmit file to peer:%s, port:%d, fd: %d\n", system_inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port), fd);
以上是我的代码,是服务器接收到客户端的连接后accept一个fd之后开个线程进行处理工作,但是发现debug信息是这样的:
file: accept non-dr 192.168.20.127, cur num:1, fd: 15
file: accept non-dr 192.168.20.114, cur num:2, fd: 16
file: accept non-dr 192.168.20.109, cur num:3, fd: 17
file: current connect peer[3] lager then MaxConnection[3], or there is no client 192.168.20.107, fd: 18
file: current connect peer[3] lager then MaxConnection[3], or there is no client 192.168.20.129, fd: 18
file: start to transmit file to peer:192.168.20.129, port:55774, fd: 15
file: size: 14286852
file: start to transmit file to peer:192.168.20.129, port:60007, fd: 16
file: size: 14286852
file: start to transmit file to peer:192.168.20.109, port:53858, fd: 17
file: size: 14286852
file: send 14286852 bytes finished
file: peer[192.168.20.114] finished, writelen: 14286852, status: 1
竟然出现了两个192.168.20.129,刚开始怀疑getpeername调用的时机不对。但是最后发现了问题原因在inet_ntoa上面。
因为inet_ntoa是只有1个唯一的static buffer来进行字符串处理的,但线程多的时候,相当于所有的线程都共享inet_ntoa里的全局静态变量。