我正在做一个使用套接字的应用程序,所以我在数组中保存套接字句柄。我有以下代码:
while(0 == 0){
int * tx = (int*)(malloc((nr_con + 2) * sizeof(int)));
if (conexiuni != NULL)
{
syslog(LOG_NOTICE,"Ajung la eliberare %d",nr_con);
memcpy(&tx[0],&conexiuni[0],(sizeof(int) * (nr_con)));
syslog(LOG_NOTICE,"Ajung la eliberare %d",nr_con);
free(conexiuni);
}
conexiuni = tx;
syslog(LOG_NOTICE,"Ajung la mama %d",nr_con);
//The line bellow causes a segfault at second connection
if ((conexiuni[nr_con] = accept(hsock,(sockaddr*)(&sadr),&addr_size)) != -1)
{
nr_con++;
syslog(LOG_NOTICE,"Primesc de la %s",inet_ntoa(sadr.sin_addr));
syslog(LOG_NOTICE,"kkt %d",conexiuni[nr_con - 1]);
int * sz = (int*)malloc(sizeof(int));
*sz = conexiuni[nr_con - 1];
syslog(LOG_NOTICE,"after %d",*sz);
pthread_create(&tidi,0,&ConexiuniHandler, sz);
}
}
当我第二次连接分配数组时,程序崩溃了。我究竟做错了什么?我在Windows上尝试了相同的代码,它运行良好,但在Linux上崩溃。
答案 0 :(得分:4)
使用std::vector
。
糟糕!您的答案无法提交,因为:
身体必须至少30个字符;你进入了19
答案 1 :(得分:2)
我认为您想要做的是拥有一个接受连接的服务器,然后当接受连接时,您启动一个线程来处理该连接请求。因此,每次执行接受时,您都希望启动一个线程并为其提供套接字句柄。您还可以跟上数组中的所有套接字句柄,当您接受新的连接请求时,它会动态增加。
以下是建议的方法。我没有做任何测试,也没有编译这段代码,但它是一个开始的地方。我正在做的一件事是每次调整数组大小时,增加16个块的套接字句柄数组。我这样做是因为它可以使内存管理器的工作更容易,并通过减少对malloc()
的调用次数来减少碎片数量。
int nr_con = 0; // we start off with no connections
int block_con = 16; // number of blocks to allocate each time we increase the array
SOCKET *conexiuni = malloc ((nr_con + block_con) * sizeof(SOCKET));
while(1) {
syslog (LOG_NOTICE, "Ajung la mama %d", nr_con);
// wait for a connection request to come in. if it does, log the request
// then create a thread to handle the request providing the socket to the thread.
// we are keeping an array of the sockets that is dynamically increased so
// we will allocate blocks of 16 at a time as we lengthen the array.
if ((conexiuni[nr_con] = accept (hsock, (sockaddr*)(&sadr), &addr_size)) != -1)
{
block_con--;
if (block_con < 1) {
{
// so lets add another block to our array by allocating the memory
// then copying the current array to the new memory area then freeing
// the old memory area which is no longer needed.
block_con = 16;
SOCKET *pTemp = malloc(nr_con + block_con) * sizeof(SOCKET));
syslog (LOG_NOTICE, "Ajung la eliberare %d", nr_con);
memcpy (pTemp, conexiuni, (sizeof(SOCKET) * (nr_con + 1)));
syslog (LOG_NOTICE, "Ajung la eliberare %d", nr_con);
free (conexiuni);
conexiuni = pTemp;
}
syslog (LOG_NOTICE, "Primesc de la %s", inet_ntoa(sadr.sin_addr));
syslog (LOG_NOTICE, "kkt %d", conexiuni[nr_con]);
SOCKET *sz = conexiumi + nr_con;
syslog (LOG_NOTICE, "after %d", *sz);
// start the thread which is to service this connection request.
pthread_create (&tidi, 0, &ConexiuniHandler, sz);
nr_con++;
}
}
然而,有一些类似的问题。首先,在上面的示例中,由于无法提供内存请求,malloc()
返回NULL指针时,我没有处理内存不足错误。
第二个问题是线程在数组动态扩展之前不会访问指向套接字的指针,因为在动态重新分配期间释放了指针,因此提供的指针无效。因此,如果您有很多连接快速进入,这可能是一个问题。至少线程应该做的第一件事就是制作套接字句柄的本地副本。
另一个问题是,您将如何返回数组以确定哪些套接字仍然有效并且打开,哪些套接字关闭时过时。您是否只是在连接请求进入后动态分配空间,直到服务器启动并运行几天后内存不足为止?
您应该使用SOCKET而不是使用int,因为它是实际的数据类型。我意识到在大多数情况下,SOCKET实际上是一个int,但通常在这些问题上更精确。