Socket中的一些函数简介

本博客主要参考:
http://www.cnblogs.com/L-hq815/archive/2012/07/09/2583043.html
https://blog.csdn.net/tennysonsky/article/details/45621341
若有侵权,请联系删除

socket()函数

#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);

参数domain表示所用的通信域,一般使用AF_INET,type表示套接字类型,主要有SOCKET_STREAM(流式套接字)、SOCK_DGRAM(数据包套接字)等。protocol表示所用的协议。

  • 类型为SOCK_STREAM的套接字表示一个双向的字节流,与管道类似。流式的套接字在进行数据收发之前必须已经连接,连接使用connect()函数进行。一旦连接,可以使用read()或者write()函数进行数据的传输。流式通信方式保证数据不会丢失或者重复接收,当数据在一段时间内任然没有接受完毕,可以将这个连接人为已经死掉。
  • SOCK_DGRAM和SOCK_RAW 这个两种套接字可以使用函数sendto()来发送数据,使用recvfrom()函数接受数据,recvfrom()接受来自制定IP地址的发送方的数据。
  • SOCK_PACKET是一种专用的数据包,它直接从设备驱动接受数据。

这个函数主要用于建立一个对应参数的套接字文件描述符,根据大佬们的话来说就是Unix一切皆文件,如果出现错误则会返回errno

bind()函数

#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);

bind()函数主要用以将套接字和本地的端口链接起来。sockfd 是调用 socket 返回的文件描述符。my_addr 是指向数据结构 struct sockaddr 的指针,它保存你的地址(即端口和 IP 地址) 信息。 addrlen 设置为 sizeof(struct sockaddr)。

一个例子

  struct sockaddr_in my_addr;
  sockfd = socket(AF_INET, SOCK_STREAM, 0); /*需要错误检查 */
  my_addr.sin_family = AF_INET; /* host byte order */
  my_addr.sin_port = htons(MYPORT); /* short, network byte order */
  my_addr.sin_addr.s_addr = inet_addr("132.241.5.10");
   bzero(&(addr.sin_zero),sizeof(addr.sin_zero)); /* 需要用bzero或者memset清零 */
  /* don't forget your error checking for bind(): */
  bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
  /* 强制转化为sockaddr */

注意,选择地址时可以采取一些自动处理的办法,以保证程序的可移植性。
my_addr.sin_port = 0; /* 随机选择一个没有使用的端口 */
my_addr.sin_addr.s_addr = INADDR_ANY; /* 使用自己的IP地址 */

connect()函数

#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

connect函数用以与指定套接字的连接,它的功能和bind()类似,参数也基本相同,不一样的是它会自动检查是否绑定端口,若没有绑定,则它会自动绑定一个本地端口。

调用的方式也和bind()函数一样,这里就不再举例了。

listen()函数

#include <sys/socket.h>
int listen( int sockfd, int backlog);

这个函数用以创建一个套接口并监听申请的连接。与上面不同,貌似这个函数不需要和远程的某个地址相连。connect()多用于客户端,listen()和之后介绍的accept()主要用于服务器,是一种被动连接。

listen() 函数的第二个参数( backlog)的作用是告诉内核连接队列的长度。 任何一个给定的监听套接口监听两个队列:未完成队列和已完成队列。
调用顺序

socket();
bind();
listen();
/* accept() 应该在这 */

accept()函数

#include <sys/socket.h>
int accept(int sockfd, void *addr, int *addrlen);

sockfd是套接字描述符,addr 是个指 向局部的数据结构 sockaddr_in 的指针。这是要求接入的信息所要去的地方(你可以测定哪个地址在哪个端口呼叫你。在它的地址传递给 accept 之前,addrlen 是个局部的整形变量,设置为 sizeof(struct sockaddr_in)。
这个函数用于和listen()配套使用。这里或许要引入多线程,一个线程用于继续监听端口,另一个线程用于处理这个接收到的数据。

send()和recv()函数

这两个函数用于流式套接字或者数据报套接字的通讯。

int send(int sockfd, const void *msg, int len, int flags);

sockfd 是你想发送数据的套接字描述符(或者是调用 socket() 或者是 accept() 返回的。)msg 是指向你想发送的数据的指针。len 是数据的长度。 把flags设置为 0 就可以了
这两个函数用于流式套接字或者数据报套接字的通讯。

int recv(int sockfd, void *buf, int len, unsigned int flags);

sockfd 是要读的套接字描述符。buf 是要读的信息的缓冲。len 是缓 冲的最大长度。flags 可以设置为0。(请参考recv() 的 man page。) recv() 返回实际读入缓冲的数据的字节数。或者在错误的时候返回-1, 同时设置 errno。

sendto() 和 recvfrom()函数

这两个函数用于无连接数据报套接字的通讯。

int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);

除了另外的两个信息外,其余的参数和函数 send() 是一样的。to是个指向数据结构 struct sockaddr 的指针,它包含了目的地的 IP 地址和端口信息。tolen 可以简单地设置为sizeof(struct sockaddr)。 和函数 send() 类似,sendto() 返回实际发送的字节数(它也可能小于 你想要发送的字节数!),或者在错误的时候返回 -1。

int recvfrom(int sockfd, void *buf, int len, unsigned int flags,  struct sockaddr *from, int *fromlen);

同样,除了两个增加的参数外,这个函数和 recv() 也是一样的。from 是一个指向局部数据结构 struct sockaddr 的指针,它的内容是源机器的 IP 地址和端口信息。fromlen 是个 int 型的局部指针,它的初始值为 sizeof(struct sockaddr)。函数调用返回后,fromlen 保存着实际储存在 from 中的地址的长度。recvfrom() 返回收到的字节长度,或者在发生错误后返回 -1。

注意: 如果你用 connect()连接一个数据报套接字,你可以简单的调用send()和recv() 来足你的要求。这个时候依然是数据报套接字,依然使用UDP,系统套接字接口会为你自动加上了目标和源的信息。

lose()和shutdown()函数

关闭数据所采用的两种方式。

int close(int sockfd);

或者采用带有控制的shutdown()函数

int shutdown(int sockfd, int how);

sockfd 是你想要关闭的套接字文件描述复。how的值可以是下面三者之一:

  • 0 – 不允许接受
  • 1 – 不允许发送
  • 2 – 不允许发送和接受(和 close() 一样)

getpeername()函数

函数 getpeername() 告诉你在连接的流式套接字上谁在另外一边。

#include <sys/socket.h>
int getpeername(int sockfd, struct sockaddr *addr, int *addrlen);

sockfd 是连接的流式套接字的描述符。addr 是一个指向结构 struct sockaddr (或者是 struct sockaddr_in) 的指针,它保存着连接的另一边的 信息。addrlen 是一个 int 型的指针,它初始化为 sizeof(struct sockaddr)。 函数在错误的时候返回 -1,设置相应的 errno。

gethostname()函数

返回你程序所运行的机器的主机名字。然后你可以使用 gethostbyname() 以获得你的机器的 IP 地址。

#include <unistd.h>
int gethostname(char *hostname, size_t size);

参数很简单,hostname 是一个字符数组指针,它将在函数返回时保存 主机名。size是hostname 数组的字节长度。

最后附上一张TCP的网络编程开发核心步骤图:

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值