LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 776|回复: 6

编译时期莫名其妙的错误

[复制链接]
发表于 2003-10-14 10:28:51 | 显示全部楼层 |阅读模式
[root@BillingServer test]# gcc -o tcpsock tcpsock.c
In file included from tcpsock.c:4:
tcpsock.h:17:28: sys/netinet/in.h: 没有那个文件或目录
tcpsock.h:18:29: sys/netinet/tcp.h: 没有那个文件或目录
tcpsock.c: In function `CreateConnection':
tcpsock.c:130: incompatible types in assignment
tcpsock.c: In function `AcceptConnection':
tcpsock.c:142: warning: passing arg 2 of `accept' from incompatible pointer type
tcpsock.c:162: incompatible types in assignment
tcpsock.c: In function `QuerySocketsMsg':
tcpsock.c:209: invalid operands to binary /
tcpsock.c:215: invalid operands to binary /
tcpsock.c:224: invalid operands to binary /
tcpsock.c:256:2: warning: no newline at end of file

这个文件原来是sco unix里头的,是不是和linux里的头文件有区别,要屏蔽一些头文件?

tcpsock.c文件如下:


  1. /* File Name: tcpsock.c */
  2. /* 本文件给出九个函数的源代码,其中部分地方给出中文注释 */

  3. #include "tcpsock.h"

  4. int InitSocketsStruct(char * servicename)
  5. /* Initialize Sockets structure. If succeed then return 1, else return error code (<0) */
  6. /* 此函数用于只需要主动套接字的客户程序,它用来获取服务信息.服务的定义在/etc/services文件中 */
  7. {
  8.         struct servent *servrec;
  9.         struct sockaddr_in serv_addr;
  10.         if ((servrec = getservbyname(servicename, "tcp")) == NULL)
  11.         {
  12.                 return(-1);
  13.         }
  14.        
  15.         bzero((char *)&Mysock, sizeof(Sockets));
  16.         Mysock.Port = servrec->s_port; /* Service Port in Network Byte Order */
  17.         return(1);
  18. }


  19. int InitPassiveSock(char * servicename)
  20. /* Initialize Passive Socket. If succeed then return 1, else return error code (<0) */
  21. /* 此函数用于需要被动套接字的服务器程序,它除了获取服务信息外,还建立一个被动套接字.*/

  22. {
  23.         int mainsock, flag=1;
  24.         struct servent *servrec;
  25.         struct sockaddr_in serv_addr;
  26.         if ((servrec = getservbyname(servicename, "tcp")) == NULL)
  27.         {
  28.                 return(-1);
  29.         }
  30.        
  31.         bzero((char *)&Mysock, sizeof(Sockets));
  32.         Mysock.Port = servrec->s_port; /* Service Port in Network Byte Order */

  33.         if((mainsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  34.         {
  35.                 return(-2);
  36.         }

  37.         bzero((char *)&serv_addr, sizeof(serv_addr));
  38.         serv_addr.sin_family = AF_INET;
  39.         serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* 任意网络接口 */
  40.         serv_addr.sin_port = servrec->s_port;
  41.         if (bind(mainsock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
  42.         {
  43.                 close(mainsock);
  44.                 return(-3);
  45.         }

  46.         if (listen(mainsock, 5) == -1) /* 将主动套接字变为被动套接字,准备好接收连接 */
  47.         {
  48.                 close(mainsock);
  49.                 return(-4);
  50.         }

  51.         /* Set this socket as a Non-blocking socket. */
  52.         if (ioctl(mainsock, FIONBIO, &flag) == -1)
  53.         {
  54.                 close(mainsock);
  55.                 return(-5);
  56.         }

  57.         Mysock.DaemonSock = mainsock;
  58.         FD_SET(mainsock, &Mysock.readfds); /* 申明对主套接字“可读”感兴趣 */
  59.         FD_SET(mainsock, &Mysock.exceptfds); /* 申明对主套接字上例外事件感兴趣 */
  60.         return(1);
  61. }


  62. void CloseMainSock()
  63. /* 关闭主套接字,并清除对它上面事件的申明.在程序结束前关闭主套接字是一个好习惯 */
  64. {
  65.         close(Mysock.DaemonSock);
  66.         FD_CLR(Mysock.DaemonSock, &Mysock.readfds);
  67.         FD_CLR(Mysock.DaemonSock, &Mysock.exceptfds);
  68. }

  69. int CreateConnection(struct in_addr *sin_addr)
  70. /* Create a Connection to remote host which IP address is in sin_addr.
  71.    Param: sin_addr indicates the IP address in Network Byte Order.
  72.    if succeed return the socket number which indicates this connection,
  73.    else return error code (<0) */
  74. {
  75.         struct sockaddr_in server; /* server address */
  76.         int tmpsock, flag=1, i;

  77.         if ((tmpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  78.                 return(-1);

  79.         server.sin_family = AF_INET;
  80.         server.sin_port = Mysock.Port;
  81.         server.sin_addr.s_addr = sin_addr->s_addr;

  82.         /* Set this socket as a Non-blocking socket. */
  83.         if (ioctl(tmpsock, FIONBIO, &flag) == -1)
  84.         {
  85.                 close(tmpsock);
  86.                 return(-2);
  87.         }

  88.         /* Connect to the server. */
  89.         if (connect(tmpsock, (struct sockaddr *)&server, sizeof(server)) < 0)
  90.         {
  91.                 if ((errno != EWOULDBLOCK) && (errno != EINPROGRESS))
  92.                 {
  93.                         /* 如果错误代码是EWOULDBLOCK和EINPROGRESS,则不用关闭套接字,
  94.                            因为系统将在之后继续为套接字建立连接,连接是否建立成功可用select()函数来检测套接字是否“可写”来确定.*/
  95.                         close(tmpsock);
  96.                         return(-3); /* Connect error. */
  97.                 }
  98.         }

  99.         FD_SET(tmpsock, &Mysock.readfds);
  100.         FD_SET(tmpsock, &Mysock.writefds);
  101.         FD_SET(tmpsock, &Mysock.exceptfds);
  102.        
  103.         i = 0;
  104.         while (Mysock.Sockets != 0) i++; /* look for a blank sockets position */

  105.         if (i >= 64)
  106.         {
  107.                 close(tmpsock);
  108.                 return(-4); /* too many connections */
  109.         }

  110.         Mysock.Sockets = tmpsock;
  111.         Mysock.SockNum++;
  112.         return(i);
  113. }

  114. int AcceptConnection(struct in_addr *IPaddr)
  115. /* Accept a connection. If succeed, return the data sockets number, else return -1. */
  116. {
  117.         int newsock, len, flag=1, i;
  118.         struct sockaddr_in addr;
  119.         len = sizeof(addr);
  120.         bzero((char *)&addr, len);
  121.         if ((newsock = accept(Mysock.DaemonSock, &addr, &len)) == -1)
  122.                 return(-1); /* Accept error. */

  123.         /* Set this socket as a Non-blocking socket. */
  124.         ioctl(newsock, FIONBIO, &flag);
  125.         FD_SET(newsock, &Mysock.readfds);
  126.         FD_SET(newsock, &Mysock.writefds);
  127.         FD_SET(newsock, &Mysock.exceptfds);
  128.        
  129.         /* Return IP address in the Parameter. */
  130.         IPaddr->s_addr = addr.sin_addr.s_addr;

  131.         i = 0;
  132.         while (Mysock.Sockets != 0) i++; /* look for a blank sockets position */
  133.         if (i >= 64)
  134.         {
  135.                 close(newsock);
  136.                 return(-4); /* too many connections */
  137.         }
  138.        
  139.         Mysock.Sockets = newsock;
  140.         Mysock.SockNum++;
  141.         return(i);
  142. }

  143. int CloseConnection(int Sockno)
  144. /* Close a connection indicated by Sockno. */
  145. {
  146.         int retcode;

  147.         if ((Sockno >= 64) || (Sockno < 0) || (Mysock.Sockets[Sockno] == 0))
  148.                 return(0);

  149.         retcode = close(Mysock.Sockets[Sockno]);
  150.         FD_CLR(Mysock.Sockets[Sockno], &Mysock.readfds);
  151.         FD_CLR(Mysock.Sockets[Sockno], &Mysock.writefds);
  152.         FD_CLR(Mysock.Sockets[Sockno], &Mysock.exceptfds);

  153.         Mysock.Sockets[Sockno] = 0;
  154.         Mysock.SockNum--;
  155.         return(retcode);
  156. }


  157. int QuerySocketsMsg()
  158. /* Query Sockets Message. If succeed return message number, else return -1.
  159.    The message information stored in struct SockMsg. */
  160. {
  161.         fd_set rfds, wfds, efds;
  162.         int retcode, i;
  163.         struct timeval TimeOut;
  164.        
  165.         rfds = Mysock.readfds;
  166.         wfds = Mysock.writefds;
  167.         efds = Mysock.exceptfds;
  168.         TimeOut.tv_sec = 0; /* 立即返回,不阻塞.*/
  169.         TimeOut.tv_usec = 0;
  170.        
  171.         bzero((char *)&SockMsg, sizeof(SockMsg));

  172.         if ((retcode = select(64, &rfds, &wfds, &efds, &TimeOut)) == 0)
  173.                 return(0);
  174.         if (FD_ISSET(Mysock.DaemonSock, &rfds))
  175.                 SockMsg.AcceptNum = 1; /* some client call server. */

  176.         for (i=0; i<64; i++) /* Data in message */
  177.         {
  178.                 if ((Mysock.Sockets > 0) && (FD_ISSET(Mysock.Sockets, &rfds)))
  179.                 SockMsg.ReadQueue[SockMsg.ReadNum++] = i;
  180.         }

  181.         for (i=0; i<64; i++) /* Data out ready message */
  182.         {
  183.                 if ((Mysock.Sockets > 0) && (FD_ISSET(Mysock.Sockets, &wfds)))
  184.                 SockMsg.WriteQueue[SockMsg.WriteNum++] = i;
  185.         }

  186.         if (FD_ISSET(Mysock.DaemonSock, &efds))
  187.                 SockMsg.AcceptNum = -1; /* server socket error. */

  188.         for (i=0; i<64; i++) /* Error message */
  189.         {
  190.                 if ((Mysock.Sockets > 0) && (FD_ISSET(Mysock.Sockets, &efds)))
  191.                 SockMsg.ExceptQueue[SockMsg.ExceptNum++] = i;
  192.         }
  193.        
  194.         return(retcode);
  195. }

  196. int SendPacket(int Sockno, void *buf, int len)
  197. /* Send a packet. If succeed return the number of send data, else return -1 */
  198. {
  199.         int actlen;
  200.         if ((Sockno >= 64) || (Sockno < 0) || (Mysock.Sockets[Sockno] == 0))
  201.                 return(0);

  202.         if ((actlen = send(Mysock.Sockets[Sockno], buf, len, 0)) < 0)
  203.                 return(-1);
  204.        
  205.         return(actlen);
  206. }

  207. int RecvPacket(int Sockno, void *buf, int size)
  208. /* Receive a packet. If succeed return the number of receive data, else if the connection
  209.    is shutdown by peer then return 0, otherwise return 0-errno */
  210. {
  211.         int actlen;
  212.         if ((Sockno >= 64) || (Sockno < 0) || (Mysock.Sockets[Sockno] == 0))
  213.                 return(0);
  214.        
  215.         if ((actlen = recv(Mysock.Sockets[Sockno], buf, size, 0)) < 0)
  216.                 return(0-errno);
  217.        
  218.         return(actlen); /* actlen是接收的数据长度,如果为零,指示连接被对方关闭.*/
  219. }
复制代码
 楼主| 发表于 2003-10-14 10:35:01 | 显示全部楼层
黄叶兄,发错了版区了,不好意思
希望转到程序设计区,拜托
……
thx
发表于 2003-10-14 21:22:35 | 显示全部楼层
->tcpsock.h:17:28: sys/netinet/in.h: 没有那个文件或目录
->tcpsock.h:18:29: sys/netinet/tcp.h: 没有那个文件或目录
应该是netinet/xx.h,没有sys/

->tcpsock.c:142: warning: passing arg 2 of `accept' from incompatible pointer type
accept的第二个参数是struct sockaddr *,应该转换一下

->tcpsock.c:256:2: warning: no newline at end of file
文件最后应该有个换行符

其它的还没搞清,能不能把tcpsock.h贴出来看看?
发表于 2003-10-14 21:59:25 | 显示全部楼层
请楼主贴代码时注意保证代码缩进,以便阅读。方法可以在置顶的贴子中找到。
 楼主| 发表于 2003-10-15 09:58:09 | 显示全部楼层
/*  tcpsock.h包括socket程序经常用到的系统头文件,
    并定义了我们自己的两个数据结构及其实例变量,以及我们提供的函数说明.*/

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/tape.h>-------------编译时期说没有tape.h这个文件
#include <sys/signal.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/netinet/in.h>-----------编译时期说没有这个文件
#include <sys/netinet/tcp.h>------------编译时期说没有这个文件
#include <arpa/inet.h>
#include <netdb.h>

typedef struct SocketsMsg{ /* 套接字消息结构 */
        int AcceptNum; /* 指示是否有外来连接等待接收 */
        int ReadNum; /* 有外来数据等待读取的连接数 */
        int ReadQueue[32]; /* 有外来数据等待读取的连接队列 */
        int WriteNum; /* 可以发送数据的连接数 */
        int WriteQueue[32]; /* 可以发送数据的连接队列 */
        int ExceptNum; /* 有例外的连接数 */
        int ExceptQueue[32]; /* 有例外的连接队列 */
}SocketsMsg;

typedef struct Sockets { /* 套接字结构 */
        int DaemonSock; /* 主套接字 */
        int SockNum; /* 数据套接字数目 */
        int Sockets[64]; /* 数据套接字数组 */
        fd_set readfds, writefds, exceptfds; /* 要被检测的可读、可写、例外的套接字集合 */
        int Port; /* 端口号 */
}Sockets;

Sockets Mysock; /* 全局变量 */
SocketsMsg SockMsg;

int InitSocketsStruct(char * servicename) ;
int InitPassiveSock(char * servicename) ;
void CloseMainSock();
int CreateConnection(struct in_addr *sin_addr);
int AcceptConnection(struct in_addr *IPaddr);
int CloseConnection(int Sockno);
int QuerySocketsMsg();
int SendPacket(int Sockno, void *buf, int len);
int RecvPacket(int Sockno, void *buf, int size);

client.c
/* 客户程序在执行时,先初始化数据结构,然后等待用户输入命令。它识别四个命令:
   conn(ect): 和服务器建立连接;
   send: 给指定连接发送数据;
   clos(e): 关闭指定连接;
   quit: 退出客户程序。
*/

#include "tcpsock.h"

main(argc, argv)
int argc;
char **argv;
{
        char cmd_buf[16];
        struct in_addr sin_addr;
        int sockno1, retcode;
        char *buf = "This is a string for test.";

        sin_addr.s_addr = inet_addr("166.111.5.249"); /* 运行服务器程序的主机的IP地址 */

        if ((retcode = InitSocketsStruct("TestService")) < 0)  /* 初始化数据结构 */
        {
                printf("InitSocketsStruct: error code = %d\n", retcode);
                exit(1);
        }

        while (1)
        {
                printf(">");
                gets(cmd_buf);
                if (!strncmp(cmd_buf, "conn", 4))
                {
                        retcode = CreateConnection(&sin_addr); /* 建立连接 */
                        printf("return code: %d\n", retcode);
                }
       
                else if(!strncmp(cmd_buf, "send", 4))
                {
                        printf("Sockets Number:");
                        scanf("%d", &sockno1);
                        retcode = SendPacket(sockno1, buf, 26); /* 发送数据 */
                        printf("return code: %d\n", retcode, sizeof(buf));
                }
               
                else if (!strncmp(cmd_buf, "close", 4))
                {
                        printf("Sockets Number:");
                        scanf("%d", &sockno1);
                        retcode = CloseConnection(sockno1); /* 关闭连接 */
                        printf("return code: %d\n", retcode);
                }

                else if (!strncmp(cmd_buf, "quit", 4))
                        exit(0);
       
                else
                        putchar(\007);
        } /* end while */
}

server.c
/* File Name: server.c */
/* 这是一个很简单的重复服务器程序,它初始化好被动套接字后,循环等待接收连接.如果接收到连接,
   它显示数据套接字序号和客户端的IP地址;如果数据套接字上有数据到来,它接收数据并显示该连接的数据套接字序号和接收到的字符串.*/

#include "tcpsock.h"

main(argc, argv)
int argc;
char **argv;
{
        struct in_addr sin_addr;
        int retcode, i;
        char buf[32];
        /* 对于服务器程序,它经常是处于无限循环状态,只有在用户主动kill该进程或系统关机时,它才结束.
           对于使用kill强行终止的服务器程序,由于主套接字没有关闭,资源没有主动释放,可能会给随后的
           服务器程序重新启动产生影响.因此,主动关闭主套接字是一个良好的变成习惯.下面的语句使程序
           在接收到SIGINT、SIGQUIT和SIGTERM等信号时先执行CloseMainSock()函数关闭主套接字,
           然后再结束程序.因此,在使用kill强行终止服务器进程时,应该先使用kill -2 PID给服务器程序
           一个消息使其关闭主套接字,然后在用kill -9 PID强行结束该进程.*/
       
        (void) signal(SIGINT, CloseMainSock);
        (void) signal(SIGQUIT, CloseMainSock);
        (void) signal(SIGTERM, CloseMainSock);

        if ((retcode = InitPassiveSock("TestService")) < 0)
        {
                printf("InitPassiveSock: error code = %d\n", retcode);
                exit(-1);
        }
       
        while (1)
        {
                retcode = QuerySocketsMsg(); /* 查询网络消息 */
                if (SockMsg.AcceptNum == 1) /* 有外来连接等待接收?*/
                {
                        retcode = AcceptConnection(&sin_addr);
                        printf("retcode = %d, IP = %s \n", retcode, inet_ntoa(sin_addr.s_addr));
                }
                else if (SockMsg.AcceptNum == -1) /* 主套接字错误?*/
                        printf("Daemon Sockets error.\n");

                for (i=0; i<SockMsg.ReadNum; i++) /* 接收外来数据 */
                {
                        if ((retcode = RecvPacket(SockMsg.ReadQueue, buf, 32)) > 0)
                                printf("sockno %d Recv string = %s \n", SockMsg.ReadQueue, buf);
                        else /* 返回数据长度为零,指示连接中断,关闭套接字.*/
                                CloseConnection(SockMsg.ReadQueue);
                }
        } /* end while */
}
 楼主| 发表于 2003-10-15 10:21:04 | 显示全部楼层
->tcpsock.h:17:28: sys/netinet/in.h: 没有那个文件或目录
->tcpsock.h:18:29: sys/netinet/tcp.h: 没有那个文件或目录
应该是netinet/xx.h,没有sys/

上面文件路径老兄说得很对

->tcpsock.c:142: warning: passing arg 2 of `accept' from incompatible pointer type
accept的第二个参数是struct sockaddr *,应该转换一下

这个问题老兄的方法我试验了,不行,运行出现错误,不认识struct关键字

->tcpsock.c:256:2: warning: no newline at end of file
文件最后应该有个换行符

换行符的问题也很对,还是很谢谢老兄,希望能指出更多的错误
发表于 2003-10-15 18:51:49 | 显示全部楼层
->tcpsock.c:130: incompatible types in assignment
Mysock.Sockets = tmpsock;
这一行,Mysock.Sockets类型是int [64],tmpsock是int,类型不符

->tcpsock.c:209: invalid operands to binary /
->tcpsock.c:215: invalid operands to binary /
->tcpsock.c:224: invalid operands to binary /
都是一样的类型错误,要求的是int但提供的是指针,
Mysock.Sockets是int数组的首地址。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表