Socket编程总结

来源:互联网 发布:泰安 ug编程培训 编辑:程序博客网 时间:2024/05/20 06:25

 Socket通过以下3个属性分类:域、连接类型和协议。
域包括UNIX文件域和因特网域等。
连接类型用来区分是TCP连接还是UDP连接。
协议包括http协议、ftp协议等。
(其他知识请参考计算机网络相关教材)


创建socket

int socket(int domain, int type, int protocol);
domain可以为以下值:
    AF_UNIX    unix文件域套接字
    AF_INET    internet域套接字
type可以为以下值:
    SOCK_STREAM    TCP连接
    SOCK_DGRAM     UDP连接
protocol表明选择哪种协议,一般为0(默认协议)。
成功则返回文件描述符,通过对该描述符的读写而进行通信。
失败返回-1。

地址信息

对于unix文件域套接字,地址信息用以下结构描述:
struct sockaddr_un {
    sa_family_t sun_family;   /* AF_UNIX */
    char sun_path[];          /* pathname */
};
sun_family的值为AF_UNIX,sun_path为文件名。

对于internet域套接字则用以下结构描述地址信息:
struct sockaddr_in {
    short int sin_family;          /* AF_INET */
    unsigned short int sin_port;   /* Port number */
    struct in_addr sin_addr;       /* Internet address */
};
其中sin_family为AF_INET,sin_port为端口号,sin_addr为internet地址。
in_addr结构如下:
struct in_addr {
    unsigned long int s_addr;
};
该结构用32位整型变量来存储ip地址。标准ip地址形式可以用inet_addr()
函数转换成32位整型值。如:
    struct sockaddr_in address;
    address.sin_addr.s_addr = inet_addr("127.0.0.1");



绑定socket

int bind(int socket, const struct sockaddr *address, size_t address_len);
该函数为描述符socket分配一个地址address,address_len为地址结构的长度。
成功返回0,失败返回-1。



创建socket队列

服务器程序必须创建一个队列来存储等待处理的请求。
int listen(int socket, int backlog);
该函数为服务器端得socket创建一个长度为backlog的队列。成功返回0,失败返回-1。



请求连接

int connect(int socket, const struct sockaddr *address, size_t address_len);
客户端程序向服务程序请求连接,服务器的地址信息存储在address所指向的空间中,
address_len为该段空间的长度。socket为客户端未绑定的套接字。
成功返回0,失败返回-1。



接受请求

int accept(int socket, struct sockaddr *address, size_t *address_len);
服务器端接受请求。socket参数必须是先前调用bind()绑定过的,并且必须调用过listen(),
使socket拥有待连接队列。客户端的地址信息将会写入address所指向的空间。address_len
参数必须被设置成所期望的长度。函数返回的时候,address_len会被设置成客户端地址的
实际长度。如果队列为空,则accept函数为阻塞。成功返回0,失败返回-1。



网络信息

获取主机信息:
struct hostent *gethostbyaddr(const void *addr, size_t len, int type);
struct hostent *gethostbyname(const char *name);

其中hostent如下:
struct hostent {
    char *h_name;        /* name of the host */
    char **h_aliases;    /* list of aliases (nicknames) */
    int h_addrtype;      /* address type */
    int h_length;        /* length in bytes of the address */
    char **h_addr_list   /* list of address (network order) */
};
利用这两个函数可以通过主机名或IP地址得到主机的网络信息。

例子:


获取服务信息

struct servent *getservbyname(const char *name, const char *proto);
struct servent *getservbyport(int port, const char *proto);

proto指明的服务的协议,"tcp"对应于SOCK_STREAM(tcp连接),"udp"对应于SOCK_DGRAM(udp连接)。
name为服务的名称,port为端口号。servent结构如下:
struct servent {
    char *s_name;       /* name of the service */
    char **s_aliases;   /* list of aliases (alternative names) */
    int s_port;         /* The IP port number */
    char *s_proto;      /* The service type, usually “tcp” or “udp” */
};





数据报(UDP)

int sendto(int sockfd, void *buffer, size_t len, int flags, struct sockaddr *to, socklen_t tolen);
通过sockfd向远端主机to发送长度为len的数据报buffer。在一般应用中flags为0。

int recvfrom(int sockfd, void *buffer, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);

通过sockfd从地址为from的主机读取长度为len的数据报到buffer中。flags可为0。

例子

原创粉丝点击