C中的多客户端聊天服务器-执行问题

C中的多客户端聊天服务器-执行问题,c,client-server,chat,C,Client Server,Chat,我正在实现一个多客户端聊天服务器,出现以下错误。我从错误描述中得到的唯一提示是这是一个链接器错误。谁能帮我解决这个问题 viper[1052]% gcc -Wall -o server server.c server.c: In function âMainServerLoopâ: server.c:45: warning: pointer targets in passing argument 3 of âacceptâ differ in signedness /tmp/ccQIY5wn.o

我正在实现一个多客户端聊天服务器,出现以下错误。我从错误描述中得到的唯一提示是这是一个链接器错误。谁能帮我解决这个问题

viper[1052]% gcc -Wall -o server server.c
server.c: In function âMainServerLoopâ:
server.c:45: warning: pointer targets in passing argument 3 of âacceptâ differ in signedness
/tmp/ccQIY5wn.o: In function `MainServerLoop':
server.c:(.text+0x6c): undefined reference to `ListCreate'
server.c:(.text+0xb3): undefined reference to `ListCreate'
server.c:(.text+0xcc): undefined reference to `ListAddInt'
server.c:(.text+0x25b): undefined reference to `ListAddString'
server.c:(.text+0x27d): undefined reference to `ListAddInt'
server.c:(.text+0x4bf): undefined reference to `ListDeleteInt'
server.c:(.text+0x4cc): undefined reference to `ListDeleteString'
server.c:(.text+0x6d0): undefined reference to `ListDestroy'
server.c:(.text+0x6d9): undefined reference to `ListDestroy'
collect2: ld returned 1 exit status


/*List.h */
#ifndef __RUL_LIST_H__
#define __RUL_LIST_H__

#define MAX_STRING_LEN 21

typedef struct TAG_LIST_ITEM {
 union {
  char strval[MAX_STRING_LEN];
  int  intval;
 } values;
 struct TAG_LIST_ITEM *next;
} ListItem;

typedef struct TAG_LIST {
 ListItem *first;
 ListItem *last;
 unsigned int count;
} List;

List *ListCreate();
void ListDestroy(List **list);

void ListAddString(List *, const char *item);
void ListDeleteString(List *, const char *item);

void ListAddInt(List *, int item);
void ListDeleteInt(List *, int item);

#endif
/* List.h */

/*Server.c*/
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h> 
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "list.h"

const int SERVER_PORT   = 13000;
const int BUFFER_SIZE  = 256;
const int MAX_BUFFER_NUM = 100;

const int MAX_CLIENT_ID_LEN = MAX_STRING_LEN - 1;

void MainServerLoop(int);
void HandleClient(int connfd);
int  Max(List *list);

void MainServerLoop(int sockfd)
{
 char clientID[MAX_CLIENT_ID_LEN + 1];
 List *listClientID = ListCreate();

 int connfd, i;
 struct sockaddr_in cliAddr;
 int lenAddr = sizeof(cliAddr);

 fd_set readfds;
 FD_ZERO(&readfds);
 List *listSock = ListCreate();
 ListAddInt(listSock, sockfd);
 FD_SET(sockfd, &readfds);

 char readbuf[BUFFER_SIZE];
 char writebuf[MAX_BUFFER_NUM][BUFFER_SIZE];
 int numWriteBuf = 0;

 while (select(Max(listSock) + 1, &readfds, NULL, NULL, NULL) >= 0)
 {
  if (FD_ISSET(sockfd, &readfds))  // listening socket
  {
   connfd = accept(sockfd, (struct sockaddr *)&cliAddr, &lenAddr);
   if (connfd < 0)
   {
    printf("error while calling accept()\n");
    exit(1);
   }

   int len = read(connfd, clientID, MAX_CLIENT_ID_LEN);
   if (len > 0)
   {
    if (clientID[len] != '\0')
    {
     clientID[len] = '\0';
    }

    ListAddString(listClientID, clientID);
    printf("user %s logged in\n", clientID);
    ListAddInt(listSock, connfd);
    printf("Number of user : %d\n", listClientID->count);
    printf("Number of sock desc : %d\n" , listSock->count);

    if (numWriteBuf < MAX_BUFFER_NUM)
    {
     sprintf(writebuf[numWriteBuf++], "User %s logged in\n", clientID);
    }
   }
   else
   {
    close(connfd);
   }
  }

  ListItem *sockItem = listSock->first;
  if (sockItem) sockItem = sockItem->next; // bypass listening socket
  ListItem *clientIDItem = listClientID->first;
  while (sockItem != 0 && clientIDItem != 0)
  {
   if (FD_ISSET(sockItem->values.intval, &readfds)) // connected socket
   {
    int len = read(sockItem->values.intval, readbuf, BUFFER_SIZE - 1);
    if (len > 0)
    {
     if (numWriteBuf < MAX_BUFFER_NUM)
     {
      readbuf[len] = '\0';
      strcpy(writebuf[numWriteBuf], clientIDItem->values.strval);
      strncat(writebuf[numWriteBuf], ": ", 2);
      strncat(writebuf[numWriteBuf], readbuf, len);
      ++numWriteBuf;
     }
    }
    else if (len == 0)
    {
     ListItem *nextSock = sockItem->next;
     ListItem *nextClient = clientIDItem->next;

     FD_CLR(sockItem->values.intval, &readfds);
     close(sockItem->values.intval);
     printf("user %s logged off\n", clientIDItem->values.strval);
     ListDeleteInt(listSock, sockItem->values.intval);
     ListDeleteString(listClientID, clientIDItem->values.strval);
     printf("Number of user : %d\n", listClientID->count);
     printf("Number of sock desc : %d\n" , listSock->count);

     if (numWriteBuf < MAX_BUFFER_NUM)
     {
      sprintf(writebuf[numWriteBuf++], 
       "User %s logged off\n", clientIDItem->values.strval);
     }

     sockItem = nextSock;
     clientIDItem = nextClient;
     continue;
    }
   }

   sockItem = sockItem->next;
   clientIDItem = clientIDItem->next;
  }

  for (i = 0; i < numWriteBuf; ++i)
  {
   sockItem = listSock->first;
   if (sockItem) sockItem = sockItem->next; // bypass listening socket
   while (sockItem != 0)
   {
    write(sockItem->values.intval, writebuf[i], strlen(writebuf[i]) + 1);
    sockItem = sockItem->next;
   }
  }
  numWriteBuf = 0;

  sockItem = listSock->first;
  while (sockItem != 0)
  {
   FD_SET(sockItem->values.intval, &readfds);
   sockItem = sockItem->next;
  } 
 }

 printf("server error %d, exit !\n",errno);
 ListDestroy(&listSock);
 ListDestroy(&listClientID);
}

int Max(List *listInt)
{
 if (listInt->first == 0) return 0;

 ListItem *curItem = listInt->first;
 int max = curItem->values.intval;
 curItem = curItem->next;

 while (curItem != 0)
 {
  if (curItem->values.intval > max) 
  {
   max = curItem->values.intval;
  }
  curItem = curItem->next;
 }

 return max;
}


int main()
{
 int sockfd = socket(AF_INET, SOCK_STREAM, 0);
 if (sockfd < 0)
 {
  printf("socket() function failed\n");
  exit(1);
 }

 struct sockaddr_in addr;
 addr.sin_family = AF_INET;
 addr.sin_addr.s_addr = htonl(INADDR_ANY);
 addr.sin_port = htons(SERVER_PORT);

 if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
 {
  printf("bind() function failed\n");
  exit(1);
 }

 if (listen(sockfd, SOMAXCONN) < 0)
 {
  printf("listen() function failed\n");
  exit(1);
 }

 printf("server started, listening at port %d\n", SERVER_PORT);

 MainServerLoop(sockfd);

 return 0;
}
/* Server.c*/
viper[1052]%gcc-Wall-oserver.c
c:在函数MainServerLoop中:
server.c:45:警告:传递参数3的–accept–中的指针目标的签名性不同
/tmp/ccQIY5wn.o:在函数“MainServerLoop”中:
server.c:(.text+0x6c):对“ListCreate”的未定义引用
server.c:(.text+0xb3):对“ListCreate”的未定义引用
server.c:(.text+0xcc):对“ListAddInt”的未定义引用
server.c:(.text+0x25b):对“ListAddString”的未定义引用
server.c:(.text+0x27d):对“ListAddInt”的未定义引用
server.c:(.text+0x4bf):对“ListDeleteInt”的未定义引用
server.c:(.text+0x4cc):对“ListDeleteString”的未定义引用
server.c:(.text+0x6d0):对“ListDestroy”的未定义引用
server.c:(.text+0x6d9):对“ListDestroy”的未定义引用
collect2:ld返回了1个退出状态
/*清单h*/
#ifndef\uuu RUL\u列表\uh__
#定义规则列表__
#定义最大字符串长度21
typedef结构标记列表项{
联合{
字符字符串[最大字符串长度];
int intval;
}价值观;
结构标记\列表\项*下一步;
}清单项目;
类型定义结构标记列表{
列表项*第一;
列表项*最后;
无符号整数计数;
}名单;
List*ListCreate();
作废清单销毁(清单**清单);
无效ListAddString(列表*,常量字符*项);
无效ListDeleteString(列表*,常量字符*项);
无效列表添加项(列表*,整数项);
作废ListDeleteInt(列表*,int项);
#恩迪夫
/*清单h*/
/*服务器.c*/
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“list.h”
const int SERVER_PORT=13000;
const int BUFFER_SIZE=256;
const int MAX_BUFFER_NUM=100;
const int MAX_CLIENT_ID_LEN=MAX_STRING_LEN-1;
void MainServerLoop(int);
无效HandleClient(内部连接);
int Max(列表*列表);
void MainServerLoop(int sockfd)
{
char clientID[MAX_CLIENT_ID_LEN+1];
List*listClientID=ListCreate();
int connfd,i;
cliAddr中的结构sockaddr_;
int lenAddr=sizeof(cliAddr);
fd_设置读取FDS;
FD_零(&readfds);
List*listSock=ListCreate();
ListAddInt(listSock,sockfd);
FD_集(sockfd和readfds);
char readbuf[缓冲区大小];
char writebuf[MAX_BUFFER_NUM][BUFFER_SIZE];
int numWriteBuf=0;
while(选择(Max(listSock)+1,&readfds,NULL,NULL,NULL)>=0)
{
if(FD_ISSET(sockfd,&readfds))//侦听套接字
{
connfd=accept(sockfd,(结构sockaddr*)&cliAddr和lenAddr);
如果(connfd<0)
{
printf(“调用accept()\n时出错”);
出口(1);
}
int len=读取(connfd、clientID、MAX\u CLIENT\u ID\u len);
如果(len>0)
{
如果(clientID[len]!='\0')
{
clientID[len]='\0';
}
ListAddString(listClientID,clientID);
printf(“用户%s登录\n”,clientID);
ListAddInt(康涅狄格州listSock);
printf(“用户数量:%d\n”,listClientID->count);
printf(“sock desc的数量:%d\n”,listSock->count);
if(numWriteBuffirst;
如果(sockItem)sockItem=sockItem->next;//绕过侦听套接字
ListItem*ClientItem=listClientID->first;
while(sockItem!=0&&ClientItem!=0)
{
if(FD_ISSET(sockItem->values.intval,&readfds))//连接的套接字
{
int len=read(sockItem->values.intval、readbuf、BUFFER_SIZE-1);
如果(len>0)
{
if(numWriteBufvalues.strval);
strncat(writebuf[numWriteBuf],“:”,2);
strncat(writebuf[numWriteBuf],readbuf,len);
++numWriteBuf;
}
}
else if(len==0)
{
ListItem*nextSock=sockItem->next;
ListItem*nextClient=ClientItem->next;
FD_CLR(sockItem->values.intval和readfds);
关闭(sockItem->values.intval);
printf(“用户%s注销\n”,clientIDItem->values.strval);
ListDeleteInt(listSock,sockItem->values.intval);
ListDeleteString(listClientID,ClientItem->values.strval);
printf(“用户数量:%d\n”,listClientID->count);
printf(“sock desc的数量:%d\n”,listSock->count);
if(numWriteBufvalues.strval);
}
sockItem=NextStock;
clientIDItem=nextClient;
继续;
}
}
sockItem=sockItem->next;
clientIDItem=clientIDItem->next;
}
对于(i=0;ifirst;
如果(sockItem)sockItem=sockItem->next;//绕过侦听套接字
while(sockItem!=0)
{
写入(sockItem->values.intval,writebuf[i],strlen(writebuf[i])+1);
sockItem=sockItem->next;
}
}
numWriteBuf=0;
sockItem=listSock->first;
while(sockItem!=0)
{
FD_集(sockItem->values.intval和readfds);
sockItem=sockItem->next;
} 
}
printf(“服务器错误%d,退出!\n”,错误号);
ListDestroy(&listSock);
ListDestroy(&listClientID);
}
int Max(列表*listInt)
{
如果(listInt->first==0)返回0;
ListItem*curItem=listInt->first;
int max=curItem->values.intval;
curItem=curItem->next;
while(curItem!=0)
{
如果(curItem->values.intval>max)
{
max=curItem->values.intval;
}
curItem=curItem->next;
}
返回最大值;
}
int main()
{
int sockfd=套接字(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
printf(“socket()函数失败\n”);
出口(1);
}
地址中的结构sockaddr\u;
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=htonl(INADDR_ANY);
addr.sinu端口=htons(服务器端口);
if(bind(sockfd,(struct sockaddr*)&addr,sizeof(addr))<0)
{
printf(“bind()函数失败\n”);
出口(1);
}
如果(侦听(sockfd,SOMAXCONN)<0)
{
printf(“listen()函数失败\n”
$ gcc -Wall -o server server.c list.c