[英]C Sockets on Mac OS X
Im trying to use sockets with C. Now Im writing server side software. 我正在尝试将套接字与C一起使用。现在我正在编写服务器端软件。 My new connection handler:
我的新连接处理程序:
int handle_new_connection(SOCKET *server_socket_descriptor, unsigned int *max_known_socket_descriptor, fd_set *main_socket_set)
{
const int yes = 1;
struct sockaddr_in remote_address;
SOCKET new_connection_socket_descriptor;
int address_size;
char buffer[1000] = {0};
struct hostent *host_entry;
address_size = sizeof(struct sockaddr_in);
if (SOCKET_ERROR == (new_connection_socket_descriptor = accept((*server_socket_descriptor), (struct sockaddr *)&remote_address, (socklen_t *)&address_size)))
{
return SOCKET_ERROR;
}
if ( SOCKET_ERROR == setsockopt(new_connection_socket_descriptor, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
{
return SOCKET_ERROR;
}
printf ("Server: new connection from \'%s\' accepted successfully.\n", inet_ntoa(remote_address.sin_addr));
unsigned long remote_address_size = sizeof(remote_address.sin_addr);
if (NULL == (host_entry = gethostbyaddr((void *)&(remote_address.sin_addr), (socklen_t)&(remote_address_size), AF_INET)))
{
closesocket (new_connection_socket_descriptor);
printf ("Server: new connection from \'%s\' was immediately closed because of gethostbyaddr() failure.\n", host_entry -> h_addr);
return SOCKET_ERROR;
}
printf("Been here!\n");
return 1;
}
When new user connects (via telnet) if
sentence if (NULL == (host_entry = gethostbyaddr((void *)&(remote_address.sin_addr), (socklen_t)&(remote_address_size), AF_INET)))
brings error: Segmentation fault: 11
. 当新用户通过telnet连接时,
if
句子if (NULL == (host_entry = gethostbyaddr((void *)&(remote_address.sin_addr), (socklen_t)&(remote_address_size), AF_INET)))
带来错误: Segmentation fault: 11
。 Also, this code works perfectly on Linux. 另外,此代码在Linux上也能完美运行。 My operating system is Mac OS X. How to solve this issue?
我的操作系统是Mac OSX。如何解决此问题?
You are passing the address of remote_address_size
as the len
parameter of gethostbyaddr()
. 您正在将
remote_address_size
的地址作为gethostbyaddr()
的len
参数传递。 That parameter should not be an address, just a length value, directly. 该参数不应直接是地址,而应是长度值。
Update: 更新:
Also, you may not be getting a struct sockaddr_in
from accept()
. 另外,您可能不会从
accept()
获得struct sockaddr_in
。 For example, if the connection is an IPv6 connection, you would get a struct sockaddr_in6
. 例如,如果连接是IPv6连接,则将获得
struct sockaddr_in6
。 The safest approach would be to use a struct sockaddr_storage
. 最安全的方法是使用
struct sockaddr_storage
。
Ideally, you should switch from gethostbyaddr()
to getnameinfo()
. 理想情况下,您应该从
gethostbyaddr()
切换到getnameinfo()
。 The latter takes a struct sockaddr*
argument, to which you can supply the pointer to your struct sockaddr_storage
without having to care about what address family it actually contains. 后者采用
struct sockaddr*
参数,您可以向其提供指向struct sockaddr_storage
的指针,而不必关心它实际包含的地址族。 The man page has sample code. 手册页包含示例代码。
If you want to keep using gethostbyaddr()
, you will need to examine the sa_family
field of the struct sockaddr_storage
. 如果要继续使用
gethostbyaddr()
,则需要检查struct sockaddr_storage
的sa_family
字段。 If it's AF_INET
, you should use &((struct sockaddr_in*)&remote_address)->sin_addr
as the first argument. 如果是
AF_INET
,则应使用&((struct sockaddr_in*)&remote_address)->sin_addr
作为第一个参数。 If it's AF_INET6
, you should use &((struct sockaddr_in6*)&remote_address)->sin6_addr
. 如果是
AF_INET6
,则应使用&((struct sockaddr_in6*)&remote_address)->sin6_addr
。 The second argument would be the size of the same field. 第二个参数是相同字段的大小。
If the family is something else, you'll need to either look up how to handle that or return failure for a case not understood by your code. 如果是其他家庭,则需要查找如何处理该问题,或者针对代码无法理解的情况返回失败。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.