雅乐网

计算机技术、学习成长

编程 » Web » socket客户端和服务端代码

socket客户端和服务端代码

Socket是网络协议上的一层抽象接口。本文整理了使用socket实现客户端和服务端的流程。

客户端

1. 使用 socket() 创建TCP套接字

该函数在头文件 sys/socket.h 中:

socket函数返回一个文件描述符,代表一个套接字,它是一个整数。按照unix惯例,非负整数表示成功。

第一个参数确定套接字的通信领域,常用的有 AF_INET 表示ipv4,AF_INET6 表示ipv6

第二个参数指定套接字的类型,常用的有 SOCK_STREAM ,它表示可靠的字节流。

第三个参数指定端到端的协议,目前只支持一种协议,也就是TCP/IP协议,这里指定0

因此,可以这样使用:

2. 使用 connect() 连接服务器

首先,使用套接字需要知道通信的端点的地址,包括ip地址和端口。socket api提供了数据结构用来表示地址信息:

这个结构体的第一个成员指定地址族,常用的有 AF_INET 表示ipv4,AF_INET6 表示ipv6 。sockaddr是通用的,而不同的ip版本对应不同的结构

当sa_family指定为 AF_INET 时,就要使用 sockaddr_in 结构

我们的例子中 服务器地址是 192.168.123.163,端口是8000 ,可以按照下面这样设置sockaddr_in结构体:

设置 sin_family 为 AF_INET ,表示使用ipv4版本

使用 inet_pton 来设置 ip 地址,该函数用于把 点分十进制表示的ip地址转变为 32位的二进制表示

设置端口号8000, 函数 htons 用于 将整型变量转变成网络字节顺序

最后,使用connect()连接服务器

connect的第一个参数是套接字描述符,第二个参数就是上面的表示地址的结构体,第三个参数是表示地址结构体的大小。

由于ipv4和ipv6对应了不同的地址结构体,这里传入指针时强制转换为通用的sockaddr指针,根据第一个成员就可以区分ipv4或者是ipv6,从而可以强制转换回去。

3. 使用 send() 和 recv() 通信

send和recv函数的参数非常类似:

对于发送来说,buf指向要发送的数据,len说明要发送的字节数。

对于接收来说,buf指向接收缓冲区,len说明接收区的最大字节数。

如果没有收到消息,recv() 会阻塞。

需要注意的是,recv一次收到的数据不一定是send一次发送的数据,可能需要多次接收。上面的例子中并没有考虑。

4. 使用close()关闭socket

服务端

1. 使用 socket() 创建TCP套接字

和客户端是类似的

2. 使用 bind() 给套接字分配端口号

首先也是需要一个表示地址的结构体:

和客户端不同的地方是ip地址,设置为服务端可获得的任何ip地址。htonl 用于 将主机数(32位)转换成无符号长整型的网络字节顺序

接下来使用bind函数,将套接字和本地的一个端口相关联。

3. 使用 listen() 监听该端口,允许对该端口建立连接

listen允许客户端连接进入。如果没有执行listen,客户端的connect函数将会失败。

4.1 反复循环,每次使用 accept() 接受连接

需要写到一个循环里,以便反复多次的接收客户端的连接

accept会阻塞直到有客户端连接进来,它返回的是连接到远程连接的套接字。会把客户端的地址放入第二个参数指向的结构,第三个参数存放参数的大小。

使用函数 inet_ntop() 来把 网络字节序的32位二进制ip地址转换为点分十进制的字符串,它正好和函数 inet_pton() 作用相反

4.2 使用 send() 和 recv() 通信 ,使用 close() 关闭

这里的功能是原封不动地将收到的信息发送回去。

 

如果文章对你有帮助,欢迎点赞或打赏(金额不限)。你的打赏将全部用于支付网站服务器费用和提高网站文章质量,谢谢支持。

版权声明:

本文由 原创,商业转载请联系作者获得授权。
非商业转载请注明作者 雅乐网 ,并附带本文链接:
http://www.yalewoo.com/socket_linux.html

上一篇:

下一篇:

文章《socket客户端和服务端代码》共有1条评论:

  1. 毫无疑问,这个是要支持的!

我要评论

验证码*: 2 + 8 =