2017-09-25 16:24:16 sinat_36053757 阅读数 587

《Unix网络编程 卷1》unp.h 头文件及其编译问题

本书源码下载地址 http://www.unpbook.com
解压tar -zxvf unpv13e.tar.gz
其实各个编译过程都在README中,下面给出正确的编译过程
这里写图片描述

首先进行编译

在目录 unpv13e下依次执行以下步骤:

./configure   

cd lib   
make   

cd ../libfree   
make   

cd ../libroute  
make //这一步可能会出错,可忽略,只是表示你的系统不支持 4.4BSD,并不影响对该书的学习  

cd ../libgai   
make   

将生成的 libunp.a 静态库复制到/usr/lib/ /usr/lib64/ 中。

cd ..   //回到 unpv13e 目录   
sudo cp libunp.a /usr/lib   
sudo cp libunp.a /usr/lib64   

修改 unp.h 并将其和 config.h 拷贝到 /usr/include 中。

vim lib/unp.h //将 unp.h#include "../config.h"修改为#include "config.h"   
sudo cp lib/unp.h /usr/include   
sudo cp config.h /usr/include   

编译书本例子。注意:编译时必须加上静态链接库:-l 参数加上 libunp.a 去掉lib和后面的.a。最后得到参数-lunp

cd ./intro   
gcc daytimetcpcli.c -o daytimetcpcli -lunp 

测试上面生成的可执行文件获取本机当前日期:

./daytimetcpcli 127.0.0.1  

在进行测试时会出现以下错误:

connect error:Connection refused  

以下通过 xinetd 开启 daytime 服务程序。
其实这个是因为xinetd服务没有启动,如果没有安装,在root下
要先安装 sudo apt-get install xinetd
然后

cd/etc/xinetd.d/  

 vim daytime  

daytime 文件中的两个 disable = yes修改成 disable = no,并保存退出,然后重启 xinetd;执行/etc/init.d/xinetd restart
再次测试书本上的第一个例子:此时可以正确获取本机的当前日期;

unpv13e/intro$ ./daytimetcpcli 127.0.0.1  
09 DEC 2014 18:45:57 CST  
2015-08-03 21:14:46 u013592466 阅读数 317
这篇文章主要是针对《UNIX网络编程》里面的代码进行学习,第一个程序是回射服务器的服务器端和客户端的代码。
下面讲解一下如何运行这第一个程序。

学习unix网络编程,源代码下载:www.unpbook.com 中下载。

解压后,打开README的文件,按提示在终端用命令行进入相应的文件夹和进行make的命令。

一开始如果只是执行 ./daytimetcpcli 127.0.0.1 命令,会出现连接错误的提示,如下图所示:


先不要慌张,其实,这是由于程序是客户端程序,服务器端的程序还没有开启,这时候,要打开服务器端程序,相应的程序对应于书本的12页,也就是daytimetcpsrv.c文件。我们这里使用命令
make daytimetcpsrv


然后运行程序。
这里又会出现一个问题,如果单纯的只是  ./daytimetcpsrv 会出现bind error,


这时候要使用超级管理员的命令 sudo ./daytimetcpsrv

输入密码就可以了.

这时候这个窗口就已经是在运行服务器端程序,不能够敲其他命令了,我们要重新打开一个新的终端。
这时候在终端里面进入intro文件夹内执行 ./daytimetcpcli 127.0.0.1 命令即可看到当前时间。


至此,第一个程序才执行成功。

2019-05-08 19:50:36 lvhonglei1987 阅读数 2583

请点击下载pdf文件:

UNIX网络编程卷1:套接字联网API(第3版).pdf

更多书籍请点击 技术电子书总目录

2017-07-21 10:47:18 thinkerleo1997 阅读数 1005

《UNIX网络编程》一书中大量使用了作者自己编写的包裹函数,这些函数的声明统统写在了 unp.h 头文件中,现在将这个头文件写在博文里,方便以后查看。

注意:unp.h 和 config.h的生成, 可以上本书官网 http://www.unpbook.com/下载源代码,根据README中的使用方法生成 ,除了这两个头文件外还需要相关静态库文件的支持。笔者系统环境为Ubuntu 17.04 amd64

unp.h:

/* include unph */
/* Our own header.  Tabs are set for 4 spaces, not 8 */

#ifndef __unp_h
#define __unp_h

#include    "../config.h"   /* configuration options for current OS */
                            /* "../config.h" is generated by configure */

/* If anything changes in the following list of #includes, must change
   acsite.m4 also, for configure's tests. */

#include    <sys/types.h>   /* basic system data types */
#include    <sys/socket.h>  /* basic socket definitions */
#if TIME_WITH_SYS_TIME
#include    <sys/time.h>    /* timeval{} for select() */
#include    <time.h>        /* timespec{} for pselect() */
#else
#if HAVE_SYS_TIME_H
#include    <sys/time.h>    /* includes <time.h> unsafely */
#else
#include    <time.h>        /* old system? */
#endif
#endif
#include    <netinet/in.h>  /* sockaddr_in{} and other Internet defns */
#include    <arpa/inet.h>   /* inet(3) functions */
#include    <errno.h>
#include    <fcntl.h>       /* for nonblocking */
#include    <netdb.h>
#include    <signal.h>
#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <sys/stat.h>    /* for S_xxx file mode constants */
#include    <sys/uio.h>     /* for iovec{} and readv/writev */
#include    <unistd.h>
#include    <sys/wait.h>
#include    <sys/un.h>      /* for Unix domain sockets */

#ifdef  HAVE_SYS_SELECT_H
# include   <sys/select.h>  /* for convenience */
#endif

#ifdef  HAVE_SYS_SYSCTL_H
#ifdef  HAVE_SYS_PARAM_H
# include   <sys/param.h>   /* OpenBSD prereq for sysctl.h */
#endif
# include   <sys/sysctl.h>
#endif

#ifdef  HAVE_POLL_H
# include   <poll.h>        /* for convenience */
#endif

#ifdef  HAVE_SYS_EVENT_H
# include   <sys/event.h>   /* for kqueue */
#endif

#ifdef  HAVE_STRINGS_H
# include   <strings.h>     /* for convenience */
#endif

/* Three headers are normally needed for socket/file ioctl's:
 * <sys/ioctl.h>, <sys/filio.h>, and <sys/sockio.h>.
 */
#ifdef  HAVE_SYS_IOCTL_H
# include   <sys/ioctl.h>
#endif
#ifdef  HAVE_SYS_FILIO_H
# include   <sys/filio.h>
#endif
#ifdef  HAVE_SYS_SOCKIO_H
# include   <sys/sockio.h>
#endif

#ifdef  HAVE_PTHREAD_H
# include   <pthread.h>
#endif

#ifdef HAVE_NET_IF_DL_H
# include   <net/if_dl.h>
#endif

#ifdef HAVE_NETINET_SCTP_H
#include    <netinet/sctp.h>
#endif

/* OSF/1 actually disables recv() and send() in <sys/socket.h> */
#ifdef  __osf__
#undef  recv
#undef  send
#define recv(a,b,c,d)   recvfrom(a,b,c,d,0,0)
#define send(a,b,c,d)   sendto(a,b,c,d,0,0)
#endif

#ifndef INADDR_NONE
/* $$.Ic INADDR_NONE$$ */
#define INADDR_NONE 0xffffffff  /* should have been in <netinet/in.h> */
#endif

#ifndef SHUT_RD             /* these three POSIX names are new */
#define SHUT_RD     0   /* shutdown for reading */
#define SHUT_WR     1   /* shutdown for writing */
#define SHUT_RDWR   2   /* shutdown for reading and writing */
/* $$.Ic SHUT_RD$$ */
/* $$.Ic SHUT_WR$$ */
/* $$.Ic SHUT_RDWR$$ */
#endif

/* *INDENT-OFF* */
#ifndef INET_ADDRSTRLEN
/* $$.Ic INET_ADDRSTRLEN$$ */
#define INET_ADDRSTRLEN     16  /* "ddd.ddd.ddd.ddd\0"
                                    1234567890123456 */
#endif

/* Define following even if IPv6 not supported, so we can always allocate
   an adequately sized buffer without #ifdefs in the code. */
#ifndef INET6_ADDRSTRLEN
/* $$.Ic INET6_ADDRSTRLEN$$ */
#define INET6_ADDRSTRLEN    46  /* max size of IPv6 address string:
                   "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx" or
                   "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd\0"
                    1234567890123456789012345678901234567890123456 */
#endif
/* *INDENT-ON* */

/* Define bzero() as a macro if it's not in standard C library. */
#ifndef HAVE_BZERO
#define bzero(ptr,n)        memset(ptr, 0, n)
/* $$.If bzero$$ */
/* $$.If memset$$ */
#endif

/* Older resolvers do not have gethostbyname2() */
#ifndef HAVE_GETHOSTBYNAME2
#define gethostbyname2(host,family)     gethostbyname((host))
#endif

/* The structure returned by recvfrom_flags() */
struct unp_in_pktinfo {
  struct in_addr    ipi_addr;   /* dst IPv4 address */
  int               ipi_ifindex;/* received interface index */
};
/* $$.It unp_in_pktinfo$$ */
/* $$.Ib ipi_addr$$ */
/* $$.Ib ipi_ifindex$$ */

/* We need the newer CMSG_LEN() and CMSG_SPACE() macros, but few
   implementations support them today.  These two macros really need
    an ALIGN() macro, but each implementation does this differently. */
#ifndef CMSG_LEN
/* $$.Im CMSG_LEN$$ */
#define CMSG_LEN(size)      (sizeof(struct cmsghdr) + (size))
#endif
#ifndef CMSG_SPACE
/* $$.Im CMSG_SPACE$$ */
#define CMSG_SPACE(size)    (sizeof(struct cmsghdr) + (size))
#endif

/* POSIX requires the SUN_LEN() macro, but not all implementations DefinE
   it (yet).  Note that this 4.4BSD macro works regardless whether there is
   a length field or not. */
#ifndef SUN_LEN
/* $$.Im SUN_LEN$$ */
# define    SUN_LEN(su) \
    (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
#endif

/* POSIX renames "Unix domain" as "local IPC."
   Not all systems DefinE AF_LOCAL and PF_LOCAL (yet). */
#ifndef AF_LOCAL
#define AF_LOCAL    AF_UNIX
#endif
#ifndef PF_LOCAL
#define PF_LOCAL    PF_UNIX
#endif

/* POSIX requires that an #include of <poll.h> DefinE INFTIM, but many
   systems still DefinE it in <sys/stropts.h>.  We don't want to include
   all the STREAMS stuff if it's not needed, so we just DefinE INFTIM here.
   This is the standard value, but there's no guarantee it is -1. */
#ifndef INFTIM
#define INFTIM          (-1)    /* infinite poll timeout */
/* $$.Ic INFTIM$$ */
#ifdef  HAVE_POLL_H
#define INFTIM_UNPH             /* tell unpxti.h we defined it */
#endif
#endif

/* Following could be derived from SOMAXCONN in <sys/socket.h>, but many
   kernels still #define it as 5, while actually supporting many more */
#define LISTENQ     1024    /* 2nd argument to listen() */

/* Miscellaneous constants */
#define MAXLINE     4096    /* max text line length */
#define BUFFSIZE    8192    /* buffer size for reads and writes */

/* Define some port number that can be used for our examples */
#define SERV_PORT        9877           /* TCP and UDP */
#define SERV_PORT_STR   "9877"          /* TCP and UDP */
#define UNIXSTR_PATH    "/tmp/unix.str" /* Unix domain stream */
#define UNIXDG_PATH     "/tmp/unix.dg"  /* Unix domain datagram */
/* $$.ix [LISTENQ]~constant,~definition~of$$ */
/* $$.ix [MAXLINE]~constant,~definition~of$$ */
/* $$.ix [BUFFSIZE]~constant,~definition~of$$ */
/* $$.ix [SERV_PORT]~constant,~definition~of$$ */
/* $$.ix [UNIXSTR_PATH]~constant,~definition~of$$ */
/* $$.ix [UNIXDG_PATH]~constant,~definition~of$$ */

/* Following shortens all the typecasts of pointer arguments: */
#define SA  struct sockaddr

#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
/*
 * RFC 3493: protocol-independent placeholder for socket addresses
 */
#define __SS_MAXSIZE    128
#define __SS_ALIGNSIZE  (sizeof(int64_t))
#ifdef HAVE_SOCKADDR_SA_LEN
#define __SS_PAD1SIZE   (__SS_ALIGNSIZE - sizeof(u_char) - sizeof(sa_family_t))
#else
#define __SS_PAD1SIZE   (__SS_ALIGNSIZE - sizeof(sa_family_t))
#endif
#define __SS_PAD2SIZE   (__SS_MAXSIZE - 2*__SS_ALIGNSIZE)

struct sockaddr_storage {
#ifdef HAVE_SOCKADDR_SA_LEN
    u_char      ss_len;
#endif
    sa_family_t ss_family;
    char        __ss_pad1[__SS_PAD1SIZE];
    int64_t     __ss_align;
    char        __ss_pad2[__SS_PAD2SIZE];
};
#endif

#define FILE_MODE   (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
                    /* default file access permissions for new files */
#define DIR_MODE    (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)
                    /* default permissions for new directories */

typedef void    Sigfunc(int);   /* for signal handlers */

#define min(a,b)    ((a) < (b) ? (a) : (b))
#define max(a,b)    ((a) > (b) ? (a) : (b))

#ifndef HAVE_ADDRINFO_STRUCT
# include   "../lib/addrinfo.h"
#endif

#ifndef HAVE_IF_NAMEINDEX_STRUCT
struct if_nameindex {
  unsigned int   if_index;  /* 1, 2, ... */
  char          *if_name;   /* null-terminated name: "le0", ... */
};
/* $$.It if_nameindex$$ */
/* $$.Ib if_index$$ */
/* $$.Ib if_name$$ */
#endif

#ifndef HAVE_TIMESPEC_STRUCT
struct timespec {
  time_t    tv_sec;     /* seconds */
  long      tv_nsec;    /* and nanoseconds */
};
/* $$.It timespec$$ */
/* $$.Ib tv_sec$$ */
/* $$.Ib tv_nsec$$ */
#endif
/* end unph */

            /* prototypes for our own library functions */
int      connect_nonb(int, const SA *, socklen_t, int);
int      connect_timeo(int, const SA *, socklen_t, int);
int  daemon_init(const char *, int);
void     daemon_inetd(const char *, int);
void     dg_cli(FILE *, int, const SA *, socklen_t);
void     dg_echo(int, SA *, socklen_t);
int      family_to_level(int);
char    *gf_time(void);
void     heartbeat_cli(int, int, int);
void     heartbeat_serv(int, int, int);
struct addrinfo *host_serv(const char *, const char *, int, int);
int      inet_srcrt_add(char *);
u_char  *inet_srcrt_init(int);
void     inet_srcrt_print(u_char *, int);
void     inet6_srcrt_print(void *);
char   **my_addrs(int *);
int      readable_timeo(int, int);
ssize_t  readline(int, void *, size_t);
ssize_t  readn(int, void *, size_t);
ssize_t  read_fd(int, void *, size_t, int *);
ssize_t  recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *,
         struct unp_in_pktinfo *);
Sigfunc *signal_intr(int, Sigfunc *);
int      sock_bind_wild(int, int);
int      sock_cmp_addr(const SA *, const SA *, socklen_t);
int      sock_cmp_port(const SA *, const SA *, socklen_t);
int      sock_get_port(const SA *, socklen_t);
void     sock_set_addr(SA *, socklen_t, const void *);
void     sock_set_port(SA *, socklen_t, int);
void     sock_set_wild(SA *, socklen_t);
char    *sock_ntop(const SA *, socklen_t);
char    *sock_ntop_host(const SA *, socklen_t);
int      sockfd_to_family(int);
void     str_echo(int);
void     str_cli(FILE *, int);
int      tcp_connect(const char *, const char *);
int      tcp_listen(const char *, const char *, socklen_t *);
void     tv_sub(struct timeval *, struct timeval *);
int      udp_client(const char *, const char *, SA **, socklen_t *);
int      udp_connect(const char *, const char *);
int      udp_server(const char *, const char *, socklen_t *);
int      writable_timeo(int, int);
ssize_t  writen(int, const void *, size_t);
ssize_t  write_fd(int, void *, size_t, int);

#ifdef  MCAST
int      mcast_leave(int, const SA *, socklen_t);
int      mcast_join(int, const SA *, socklen_t, const char *, u_int);
int      mcast_leave_source_group(int sockfd, const SA *src, socklen_t srclen,
                                  const SA *grp, socklen_t grplen);
int      mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen,
                                 const SA *grp, socklen_t grplen,
                                 const char *ifname, u_int ifindex);
int      mcast_block_source(int sockfd, const SA *src, socklen_t srclen,
                            const SA *grp, socklen_t grplen);
int      mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen,
                              const SA *grp, socklen_t grplen);
int      mcast_get_if(int);
int      mcast_get_loop(int);
int      mcast_get_ttl(int);
int      mcast_set_if(int, const char *, u_int);
int      mcast_set_loop(int, int);
int      mcast_set_ttl(int, int);

void     Mcast_leave(int, const SA *, socklen_t);
void     Mcast_join(int, const SA *, socklen_t, const char *, u_int);
void     Mcast_leave_source_group(int sockfd, const SA *src, socklen_t srclen,
                                  const SA *grp, socklen_t grplen);
void     Mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen,
                                 const SA *grp, socklen_t grplen,
                                 const char *ifname, u_int ifindex);
void     Mcast_block_source(int sockfd, const SA *src, socklen_t srclen,
                            const SA *grp, socklen_t grplen);
void     Mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen,
                              const SA *grp, socklen_t grplen);
int      Mcast_get_if(int);
int      Mcast_get_loop(int);
int      Mcast_get_ttl(int);
void     Mcast_set_if(int, const char *, u_int);
void     Mcast_set_loop(int, int);
void     Mcast_set_ttl(int, int);
#endif

uint16_t    in_cksum(uint16_t *, int);

#ifndef HAVE_GETADDRINFO_PROTO
int      getaddrinfo(const char *, const char *, const struct addrinfo *,
                     struct addrinfo **);
void     freeaddrinfo(struct addrinfo *);
char    *gai_strerror(int);
#endif

#ifndef HAVE_GETNAMEINFO_PROTO
int      getnameinfo(const SA *, socklen_t, char *, size_t, char *, size_t, int);
#endif

#ifndef HAVE_GETHOSTNAME_PROTO
int      gethostname(char *, int);
#endif

#ifndef HAVE_HSTRERROR_PROTO
const char  *hstrerror(int);
#endif

#ifndef HAVE_IF_NAMETOINDEX_PROTO
unsigned int     if_nametoindex(const char *);
char            *if_indextoname(unsigned int, char *);
void             if_freenameindex(struct if_nameindex *);
struct if_nameindex *if_nameindex(void);
#endif

#ifndef HAVE_INET_PTON_PROTO
int          inet_pton(int, const char *, void *);
const char  *inet_ntop(int, const void *, char *, size_t);
#endif

#ifndef HAVE_INET_ATON_PROTO
int      inet_aton(const char *, struct in_addr *);
#endif

#ifndef HAVE_PSELECT_PROTO
int      pselect(int, fd_set *, fd_set *, fd_set *,
                 const struct timespec *, const sigset_t *);
#endif

#ifndef HAVE_SOCKATMARK_PROTO
int      sockatmark(int);
#endif

#ifndef HAVE_SNPRINTF_PROTO
int      snprintf(char *, size_t, const char *, ...);
#endif

            /* prototypes for our own library wrapper functions */
void     Connect_timeo(int, const SA *, socklen_t, int);
int      Family_to_level(int);
struct addrinfo *Host_serv(const char *, const char *, int, int);
const char      *Inet_ntop(int, const void *, char *, size_t);
void             Inet_pton(int, const char *, void *);
char            *If_indextoname(unsigned int, char *);
unsigned int         If_nametoindex(const char *);
struct if_nameindex *If_nameindex(void);
char   **My_addrs(int *);
ssize_t  Read_fd(int, void *, size_t, int *);
int      Readable_timeo(int, int);
ssize_t  Recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *,
         struct unp_in_pktinfo *);
Sigfunc *Signal(int, Sigfunc *);
Sigfunc *Signal_intr(int, Sigfunc *);
int      Sock_bind_wild(int, int);
char    *Sock_ntop(const SA *, socklen_t);
char    *Sock_ntop_host(const SA *, socklen_t);
int      Sockfd_to_family(int);
int      Tcp_connect(const char *, const char *);
int      Tcp_listen(const char *, const char *, socklen_t *);
int      Udp_client(const char *, const char *, SA **, socklen_t *);
int      Udp_connect(const char *, const char *);
int      Udp_server(const char *, const char *, socklen_t *);
ssize_t  Write_fd(int, void *, size_t, int);
int      Writable_timeo(int, int);

            /* prototypes for our Unix wrapper functions: see {Sec errors} */
void    *Calloc(size_t, size_t);
void     Close(int);
void     Dup2(int, int);
int      Fcntl(int, int, int);
void     Gettimeofday(struct timeval *, void *);
int      Ioctl(int, int, void *);
pid_t    Fork(void);
void    *Malloc(size_t);
int  Mkstemp(char *);
void    *Mmap(void *, size_t, int, int, int, off_t);
int      Open(const char *, int, mode_t);
void     Pipe(int *fds);
ssize_t  Read(int, void *, size_t);
void     Sigaddset(sigset_t *, int);
void     Sigdelset(sigset_t *, int);
void     Sigemptyset(sigset_t *);
void     Sigfillset(sigset_t *);
int      Sigismember(const sigset_t *, int);
void     Sigpending(sigset_t *);
void     Sigprocmask(int, const sigset_t *, sigset_t *);
char    *Strdup(const char *);
long     Sysconf(int);
void     Sysctl(int *, u_int, void *, size_t *, void *, size_t);
void     Unlink(const char *);
pid_t    Wait(int *);
pid_t    Waitpid(pid_t, int *, int);
void     Write(int, void *, size_t);

            /* prototypes for our stdio wrapper functions: see {Sec errors} */
void     Fclose(FILE *);
FILE    *Fdopen(int, const char *);
char    *Fgets(char *, int, FILE *);
FILE    *Fopen(const char *, const char *);
void     Fputs(const char *, FILE *);

            /* prototypes for our socket wrapper functions: see {Sec errors} */
int      Accept(int, SA *, socklen_t *);
void     Bind(int, const SA *, socklen_t);
void     Connect(int, const SA *, socklen_t);
void     Getpeername(int, SA *, socklen_t *);
void     Getsockname(int, SA *, socklen_t *);
void     Getsockopt(int, int, int, void *, socklen_t *);
#ifdef  HAVE_INET6_RTH_INIT
int      Inet6_rth_space(int, int);
void    *Inet6_rth_init(void *, socklen_t, int, int);
void     Inet6_rth_add(void *, const struct in6_addr *);
void     Inet6_rth_reverse(const void *, void *);
int      Inet6_rth_segments(const void *);
struct in6_addr *Inet6_rth_getaddr(const void *, int);
#endif
#ifdef  HAVE_KQUEUE
int      Kqueue(void);
int      Kevent(int, const struct kevent *, int,
                struct kevent *, int, const struct timespec *);
#endif
void     Listen(int, int);
#ifdef  HAVE_POLL
int      Poll(struct pollfd *, unsigned long, int);
#endif
ssize_t  Readline(int, void *, size_t);
ssize_t  Readn(int, void *, size_t);
ssize_t  Recv(int, void *, size_t, int);
ssize_t  Recvfrom(int, void *, size_t, int, SA *, socklen_t *);
ssize_t  Recvmsg(int, struct msghdr *, int);
int      Select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
void     Send(int, const void *, size_t, int);
void     Sendto(int, const void *, size_t, int, const SA *, socklen_t);
void     Sendmsg(int, const struct msghdr *, int);
void     Setsockopt(int, int, int, const void *, socklen_t);
void     Shutdown(int, int);
int      Sockatmark(int);
int      Socket(int, int, int);
void     Socketpair(int, int, int, int *);
void     Writen(int, void *, size_t);

void     err_dump(const char *, ...);
void     err_msg(const char *, ...);
void     err_quit(const char *, ...);
void     err_ret(const char *, ...);
void     err_sys(const char *, ...);

#endif  /* __unp_h */

config.h:

/* config.h.  Generated by configure.  */
/* config.h.in.  Generated from configure.in by autoheader.  */

/* CPU, vendor, and operating system */
#define CPU_VENDOR_OS "x86_64-unknown-linux-gnu"

/* Define to 1 if <netdb.h> defines struct addrinfo */
#define HAVE_ADDRINFO_STRUCT 1

/* Define to 1 if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1

/* Define to 1 if you have the `bzero' function. */
#define HAVE_BZERO 1

/* Define to 1 if the /dev/streams/xtiso/tcp device exists */
/* #undef HAVE_DEV_STREAMS_XTISO_TCP */

/* Define to 1 if the /dev/tcp device exists */
/* #undef HAVE_DEV_TCP */

/* Define to 1 if the /dev/xti/tcp device exists */
/* #undef HAVE_DEV_XTI_TCP */

/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1

/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1

/* Define to 1 if you have the `getaddrinfo' function. */
#define HAVE_GETADDRINFO 1

/* define if getaddrinfo prototype is in <netdb.h> */
#define HAVE_GETADDRINFO_PROTO 1

/* Define to 1 if you have the `gethostbyname2' function. */
#define HAVE_GETHOSTBYNAME2 1

/* Define to 1 if you have the `gethostbyname_r' function. */
#define HAVE_GETHOSTBYNAME_R 1

/* Define to 1 if you have the `gethostname' function. */
#define HAVE_GETHOSTNAME 1

/* define if gethostname prototype is in <unistd.h> */
#define HAVE_GETHOSTNAME_PROTO 1

/* Define to 1 if you have the `getnameinfo' function. */
#define HAVE_GETNAMEINFO 1

/* define if getnameinfo prototype is in <netdb.h> */
#define HAVE_GETNAMEINFO_PROTO 1

/* define if getrusage prototype is in <sys/resource.h> */
#define HAVE_GETRUSAGE_PROTO 1

/* Define to 1 if you have the `hstrerror' function. */
#define HAVE_HSTRERROR 1

/* define if hstrerror prototype is in <netdb.h> */
#define HAVE_HSTRERROR_PROTO 1

/* Define to 1 if <net/if.h> defines struct if_nameindex */
#define HAVE_IF_NAMEINDEX_STRUCT 1

/* Define to 1 if you have the `if_nametoindex' function. */
#define HAVE_IF_NAMETOINDEX 1

/* define if if_nametoindex prototype is in <net/if.h> */
#define HAVE_IF_NAMETOINDEX_PROTO 1

/* Define to 1 if you have the `inet6_rth_init' function. */
#define HAVE_INET6_RTH_INIT 1

/* Define to 1 if you have the `inet_aton' function. */
#define HAVE_INET_ATON 1

/* define if inet_aton prototype is in <arpa/inet.h> */
#define HAVE_INET_ATON_PROTO 1

/* Define to 1 if you have the `inet_pton' function. */
#define HAVE_INET_PTON 1

/* define if inet_pton prototype is in <arpa/inet.h> */
#define HAVE_INET_PTON_PROTO 1

/* Define to 1 if you have the `kevent' function. */
/* #undef HAVE_KEVENT */

/* Define to 1 if you have the `kqueue' function. */
/* #undef HAVE_KQUEUE */

/* Define to 1 if you have the `nsl' library (-lnsl). */
/* #undef HAVE_LIBNSL */

/* Define to 1 if you have the `pthread' library (-lpthread). */
#define HAVE_LIBPTHREAD 1

/* Define to 1 if you have the `pthreads' library (-lpthreads). */
/* #undef HAVE_LIBPTHREADS */

/* Define to 1 if you have the `resolv' library (-lresolv). */
/* #undef HAVE_LIBRESOLV */

/* Define to 1 if you have the `xti' library (-lxti). */
/* #undef HAVE_LIBXTI */

/* Define to 1 if you have the `mkstemp' function. */
#define HAVE_MKSTEMP 1

/* define if struct msghdr contains the msg_control member */
#define HAVE_MSGHDR_MSG_CONTROL 1

/* Define to 1 if you have the <netconfig.h> header file. */
/* #undef HAVE_NETCONFIG_H */

/* Define to 1 if you have the <netdb.h> header file. */
#define HAVE_NETDB_H 1

/* Define to 1 if you have the <netdir.h> header file. */
/* #undef HAVE_NETDIR_H */

/* Define to 1 if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1

/* Define to 1 if you have the <net/if_dl.h> header file. */
/* #undef HAVE_NET_IF_DL_H */

/* Define to 1 if you have the `poll' function. */
#define HAVE_POLL 1

/* Define to 1 if you have the <poll.h> header file. */
#define HAVE_POLL_H 1

/* Define to 1 if you have the `pselect' function. */
#define HAVE_PSELECT 1

/* define if pselect prototype is in <sys/stat.h> */
#define HAVE_PSELECT_PROTO 1

/* Define to 1 if you have the <pthread.h> header file. */
#define HAVE_PTHREAD_H 1

/* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1

/* Define to 1 if you have the `snprintf' function. */
#define HAVE_SNPRINTF 1

/* define if snprintf prototype is in <stdio.h> */
#define HAVE_SNPRINTF_PROTO 1

/* Define to 1 if <net/if_dl.h> defines struct sockaddr_dl */
/* #undef HAVE_SOCKADDR_DL_STRUCT */

/* define if socket address structures have length fields */
/* #undef HAVE_SOCKADDR_SA_LEN */

/* Define to 1 if you have the `sockatmark' function. */
#define HAVE_SOCKATMARK 1

/* define if sockatmark prototype is in <sys/socket.h> */
#define HAVE_SOCKATMARK_PROTO 1

/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1

/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1

/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1

/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1

/* Define to 1 if you have the <stropts.h> header file. */
#define HAVE_STROPTS_H 1

/* Define to 1 if `ifr_mtu' is member of `struct ifreq'. */
#define HAVE_STRUCT_IFREQ_IFR_MTU 1

/* Define to 1 if the system has the type `struct sockaddr_storage'. */
#define HAVE_STRUCT_SOCKADDR_STORAGE 1

/* Define to 1 if you have the <sys/event.h> header file. */
/* #undef HAVE_SYS_EVENT_H */

/* Define to 1 if you have the <sys/filio.h> header file. */
/* #undef HAVE_SYS_FILIO_H */

/* Define to 1 if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 1

/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1

/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1

/* Define to 1 if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1

/* Define to 1 if you have the <sys/sockio.h> header file. */
/* #undef HAVE_SYS_SOCKIO_H */

/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1

/* Define to 1 if you have the <sys/sysctl.h> header file. */
#define HAVE_SYS_SYSCTL_H 1

/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1

/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1

/* Define to 1 if you have the <sys/uio.h> header file. */
#define HAVE_SYS_UIO_H 1

/* Define to 1 if you have the <sys/un.h> header file. */
#define HAVE_SYS_UN_H 1

/* Define to 1 if you have the <sys/wait.h> header file. */
#define HAVE_SYS_WAIT_H 1

/* Define to 1 if <time.h> or <sys/time.h> defines struct timespec */
#define HAVE_TIMESPEC_STRUCT 1

/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1

/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1

/* Define to 1 if you have the `vsnprintf' function. */
#define HAVE_VSNPRINTF 1

/* Define to 1 if you have the <xti.h> header file. */
/* #undef HAVE_XTI_H */

/* Define to 1 if you have the <xti_inet.h> header file. */
/* #undef HAVE_XTI_INET_H */

/* Define to 1 if the system supports IPv4 */
#define IPV4 1

/* Define to 1 if the system supports IPv6 */
#define IPV6 1

/* Define to 1 if the system supports IPv4 */
#define IPv4 1

/* Define to 1 if the system supports IPv6 */
#define IPv6 1

/* Define to 1 if the system supports IP Multicast */
#define MCAST 1

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""

/* Define to the full name of this package. */
#define PACKAGE_NAME ""

/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""

/* Define to the version of this package. */
#define PACKAGE_VERSION ""

/* the size of the sa_family field in a socket address structure */
/* #undef SA_FAMILY_T */

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1

/* Define to 1 if the system supports UNIX domain sockets */
#define UNIXDOMAIN 1

/* Define to 1 if the system supports UNIX domain sockets */
#define UNIXdomain 1

/* 16 bit signed type */
/* #undef int16_t */

/* 32 bit signed type */
/* #undef int32_t */

/* the type of the sa_family struct member */
/* #undef sa_family_t */

/* unsigned integer type of the result of the sizeof operator */
/* #undef size_t */

/* a type appropriate for address */
/* #undef socklen_t */

/* define to __ss_family if sockaddr_storage has that instead of ss_family */
/* #undef ss_family */

/* a signed type appropriate for a count of bytes or an error indication */
/* #undef ssize_t */

/* scalar type */
/* #undef t_scalar_t */

/* unsigned scalar type */
/* #undef t_uscalar_t */

/* 16 bit unsigned type */
/* #undef uint16_t */

/* 32 bit unsigned type */
/* #undef uint32_t */

/* 8-bit unsigned type */
/* #undef uint8_t */
2015-07-19 10:39:40 world_hope 阅读数 370

  socket套接字是网络编程中最常用的方法。基于socket套接字,用c语言实现一个简单的基于c/s架构的程序,可以实现客户端和服务器端之间聊天和传文件等功能,同时服务器端实现并发。

  代码如下:

头文件:
#define __unp_h
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#define SERVPORT 3333
#define MAXDATASIZE 64

 服务器端:

#include "unp.h"
#define BACKLOG 2
#define MAX_CONNECTED_NO 10
void S_chating_function(int client_fd,int recvbytes); //服务器交流聊天函数
void S_upload_function(int client_fd,int recvbytes);  //服务器接收文件函数
char buf[MAXDATASIZE],temp[MAXDATASIZE];

void *handle(void *fd){
 int key=1;
 char option[2];
 int client_fd = (int)fd;
 int recvbytes;
 // printf("登陆服务器成功!\n");
 memset(temp,0,sizeof(temp));
 strcpy(temp,"登陆服务器成功!");  //成功连接则发送这句信息给客户端
 if(send(client_fd,temp,MAXDATASIZE,0)==-1)
 {
  perror("send"); 
  exit(1);
 }
 while(key)
 { 
  printf("return the main \n");
  memset(option,0,sizeof(option));  //开辟option空间
  if((recvbytes=recv(client_fd,option,MAXDATASIZE,0))==-1)
  {
   perror("recv");
   exit(1);
  }
  printf("the option is %s\n",option);
/*判断接收到的客户端选项*/
  switch(option[0])
 {
   case '1': S_chating_function(client_fd,recvbytes);  //选项1,聊天交流
    break;
   case '2': S_upload_function(client_fd,recvbytes);   //选项2,接收文件
    break; 
   case '3': printf("退出成功\n");                           //选项3,退出
    key=0;
    break;
   default: break;
  }
 }
  close(client_fd);
  pthread_exit(0);
}
/*服务器聊天交流函数*/
void S_chating_function(int client_fd,int recvbytes)
{
 int x=1;
 int sendbytes;
 memset(temp,0,sizeof(temp));
 strcpy(temp,"请输入信息!");  //进入聊天交流模式,服务器发送信息告诉客户端可以交流
 if(send(client_fd,temp,MAXDATASIZE,0)==-1)
 {
  perror("send"); 
  exit(1);
 }

 while(1)
  {     
  /*receive words*/
  memset(buf,0,sizeof(buf));
  if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1)  //接收客户端发送的信息
  {
   perror("recv");
   exit(1);
  }
  
  if(strcmp(buf,"exit")==0) //如果是exit则退出
  {
   printf("The chat is over exit\n");
   break;
  } 
  else
  {
   printf("对方信息: %s\n",buf); //否则显示信息
  }

  /*send words*/
  printf("我的信息: ");
  memset(buf,0,sizeof(buf));
  gets(buf); //获取服务器要发送的信息
   
  if((sendbytes=send(client_fd,buf,MAXDATASIZE,0))==-1)  //发送
  {
   perror("send"); 
   exit(1);
  }
  if(strcmp(buf,"exit")==0) //如果是exit则退出
  {
   printf("聊天结束	\n");
   break;
  }  
 }
   return ;
}

/*服务器接收文件函数*/
void S_upload_function(int client_fd,int recvbytes)
{
 int file_open,file_write;
 printf("file upload server starting...\n");

 memset(buf,0,sizeof(buf));
 if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1)  //接收文件
 {
  perror("recv");
  exit(1);
 }
  
 char filename[32]="/home/worldhope/workspace/accept.c"; 
 printf("will upload the file %s\n",filename);

 if((file_open=open(filename,O_CREAT|O_TRUNC|O_WRONLY,0644))==-1)  //打开文件wjf.c
 {
  perror("open localhost file");
  exit(1);
 }
 lseek(file_open,0,SEEK_SET);
 if(file_write=write(file_open,buf,sizeof(buf))==-1)  //写入客户端传送文件的内容
 {
  perror("writting to file error");
  exit(1);
 }
 printf("%s\n",buf);
 printf("file upload success!\n");
 close(file_open);
 return ;
}
int main(int argc,char **argv)
{
 struct sockaddr_in server_sockaddr,client_addr;
 int sin_size,recvbytes;
 int server_fd,client_fd;

/*建立socket连接*/
 if((server_fd=socket(AF_INET,SOCK_STREAM,0))==-1)
 {
  perror("socket");
  exit(1);
 }
 printf("s创建套接字成功!\n");
 bzero(&client_addr,sizeof(client_addr));
/*设置server_sockaddr结构体中相关参数*/
 server_sockaddr.sin_family=AF_INET;
 server_sockaddr.sin_port=htons(SERVPORT);
 server_sockaddr.sin_addr.s_addr=INADDR_ANY;
 bzero(&(server_sockaddr.sin_zero),8);
/*绑定函数bind*/
 if(bind(server_fd,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr))==-1)
 {
  perror("bind");
  exit(1);
 }
 printf("绑定成功 !\n");
/*调用listen函数*/
 if(listen(server_fd,BACKLOG)==-1)
 {
  perror("listen");
  exit(1);
 }
 printf("listening...\n");
 sin_size=sizeof(struct sockaddr);
/*调用accept函数,等待客户端的连接*/
 while(1){
 if((client_fd=accept(server_fd,(struct sockaddr *)&client_addr,&sin_size))==-1)
 {
  perror("accept:");
  exit(1);
 }
  printf("connection from %s ,port %d\n",inet_ntop(AF_INET,&client_addr.sin_addr,buf,sizeof(buf)),ntohs(client_addr.sin_port));
  pthread_t child_pthread;
  pthread_attr_t child_attr_t;
  pthread_attr_init(&child_attr_t);
  pthread_attr_setdetachstate(&child_attr_t,PTHREAD_CREATE_DETACHED);
  if(pthread_create(&child_pthread,&child_attr_t,handle,(void *)client_fd) < 0)
    printf("thread create fail : %s",strerror(errno));
/*获得此客户端的IP*/
// IP1=(char *)inet_ntoa(client_sockaddr.sin_addr);
}
 close(server_fd);
}

  客户端:

#include "unp.h"
void C_upload_function(int client_fd,int recvbytes);  //客户端传送文件函数
void C_chating_function(int client_fd,int recvbytes); //客户端聊天交流函数
void my_recvmsg(int client_fd,int recvbytes);             //接收信息显示函数
char buf[MAXDATASIZE],temp[MAXDATASIZE],*IP1;

int main(int argc,char **argv)
{
 int client_fd,recvbytes;
 int file_open,file_read;
 int key=1;
 
 struct hostent *host;
 struct sockaddr_in client_sockaddr;
 char option[2];

 if(argc<2) //服务器名称及IP
 {
  fprintf(stderr,"please enter the server's hostname!\n");
  exit(1);
 }
 if((host=gethostbyname(argv[1]))==NULL)
 {
  perror("gethostbyname");
  exit(1);
 }
/*建立socket连接*/
 if((client_fd=socket(AF_INET,SOCK_STREAM,0))==-1) 
 {
  perror("socket");
  exit(1);
 }

/*设置client_sockaddr结构体中相关参数*/
 memset(&client_sockaddr,0,sizeof(client_sockaddr));
 client_sockaddr.sin_family=AF_INET;
 client_sockaddr.sin_port=htons(SERVPORT);
 client_sockaddr.sin_addr.s_addr=INADDR_ANY;
 bzero(&(client_sockaddr.sin_zero),8);

/*调用connect函数主动发起对服务器端的连接*/
 if(connect(client_fd,(struct sockaddr *)&client_sockaddr,sizeof(struct sockaddr))==-1)
 {
  perror("connect");
  exit(1);
 }
 
 printf("connecting OK\n");  //连接成功显示connecting OK

 my_recvmsg(client_fd,recvbytes);  //接收服务器发送给客户端的信息并显示

 while(key)
 { 
  printf("please select the option:\n");
  printf("option1: chating\n");
  printf("option2: upload file\n");
  memset(option,0,sizeof(option));
  gets(option); //获取输入选项

  if(send(client_fd,option,sizeof(option),0)==-1)  //把输入选项发送给服务器
  {
   perror("send option"); 
   exit(1);
  }
  switch(option[0])
  {
  case '1': C_chating_function(client_fd,recvbytes); //选项1:交流聊天
    break;
  case '2': C_upload_function(client_fd,recvbytes);  //选项2:上传文件
    break;
  case '3': printf("success to quit\n");                         //选项3:退出
   key=0;
    break;
  }
 }
 close(client_fd); 
}

/*客户端上传文件函数*/
void C_upload_function(int client_fd,int recvbytes)
{
 int file_open,file_read;
 int sendbytes;
 char *filename="/home/worldhope/workspace/send.c"; //已存在的文件
 printf("will uoload file name is:%s\n",filename);

 if((file_open=open(filename,O_RDONLY))==-1)  //打开文件
 {
  perror("open will upload file");
  exit(1);
 } 
 memset(buf,0,sizeof(buf)); //开辟buf空间
 
 if((file_read=read(file_open,buf,MAXDATASIZE))==-1)  //读取文件
 {
  perror("read will upload file");
  exit(1);
 }
  
 printf("%s\n",buf);
 if((sendbytes=send(client_fd,buf,MAXDATASIZE,0))==-1)  //发送文件
 {
   perror("send"); 
   exit(1);
 }
 
 printf("file has been uploaded successfully!\n"); //上传成功 
 close(file_open); 
 
}

/*客户端交流聊天函数*/
void C_chating_function(int client_fd,int recvbytes)
{
 int sendbytes;
 my_recvmsg(client_fd,recvbytes);  //接收服务器发送给客户端的信息
 while(1){

  /*send words*/
  printf("我的信息: ");
  memset(buf,0,sizeof(buf));
  gets(buf); //获得要发送的信息
  
  if((sendbytes=send(client_fd,buf,MAXDATASIZE,0))==-1) //发送
  {
   perror("send"); 
   exit(1);
  }
  if(strcmp(buf,"exit")==0) //如果客户端输入的是exit,退出
  {
   printf("The chat is over exit\n");
   break;
  }

  /*receive words*/
  memset(buf,0,sizeof(buf)); //开辟buf空间
  if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1) //接收信息
  {
   perror("recv");
   exit(1);
  }
  if(strcmp(buf,"exit")==0) //如果服务器发送的exit,退出
  {
   printf("聊天结束\n");
   break;
  }
  else{
   printf("对方信息: %s\n",buf);
  }
 }
}

void my_recvmsg(int client_fd,int recvbytes) //接收信息并显示
{
 memset(buf,0,sizeof(buf));
 if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1)
 {
  perror("recv");
  exit(1);
 }
 else
 {
  printf("%s\n",buf);
 }
}





      

没有更多推荐了,返回首页