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