Socket服务器-客户端开发

Socket服务器和客户端开发

TCP Server
socket
bind
listen
accept
read
write
read
close
TCP Client
socket
connect
write
read
close

TCP Server:

socket()——创建套接字,建立一个网络通信的通道——>bind()——绑定信息,为套接字添加信息(IP地址和端口号)——把信息发到网络,让其它客户端接受——>listen()——监听网络——>accept()——监听到有客户端连接,就接受一个连接——>read()——在网络通道上读数据——>write()——在网络通道上写数据——>read()——关闭套接字,断开连接——>close()

TCP Client:

socket()——建立一个套接字的通道——>connect()——包含IP地址端口号——连接到网络服务器的listen,跟其建立链接——>write()——写入数据到网络通道,让网络通道的read读取到——>read()——读取网络通道中的信息——>close()

socket()函数1

创建套接字网络通信通道

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
//如果函数调用成功,会返回一个标识这个套接字的文件描述符,失败的时候返回-1。
  • domain:
    指明所使用的协议族,通常为AF_INET,表示表示互联网协议族(TCP/IP协议族);

    • AF_INET IPv4 Internet协议——国内常用
    • AF_INET6 IPv6 Internet协议——国外常用
    • AF_UNIX Unix域——本地通信
    • AF_ROUTE 路由套接字
    • AF_KEY 密钥套接字
    • AF_UNSPEC 未指定
  • type:
    指定socket的类型:

    • SOCK_STREAM:
      流式套接字提供可靠的、面向链接的通信流;它使用TCP协议,从而保证了数据传输的正确性和顺序性
    • SOCK_DGRAM:
      数据包套接字定义了一种无线连接的服务器,数据通过相互独立的报文进行传输,是无序的,并且不保证是可考的、无差错的。支持UDP连接(无连接状态的消息)
    • SOCK_RAW:
      允许程序使用底层协议,原始套接字允许对底层协议入IP或ICMP进行直接访问,功能强大,但使用较为不便,主要用于一些协议的开发。
  • protocol:
    通常赋值:“0”。

    • 0 选择type类型对应的默认协议
    • IPPROTO_TCP TCP传输协议
    • IPPROTO_UDP UDP传输协议
    • IPPROTO_SCTP SCTP传输协议
    • IPPROTO_TIPC TIPC传输协议

bind()函数

给套接字通道绑定信息

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
返回值:0 – 成功,-1 - 出错

当socket函数返回一个描述符时,只是存在于其协议族的空间中,并没有分配一个具体的协议地址(这里指IPv4/IPv6和端口号的组合),bind函数可以将一组固定的地址绑定到sockfd上。

功能:

  • 用于绑定IP地址和端口号到sockfd

参数:

  • sockfd
    是socket函数返回的描述符
  • addr
    是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针,指向要绑定给sockfd的协议地址结构,这个地址结果根据地址创建socket时的地址协议族的不同而不同
  • addrlen
    sockaddr结构体信息的大小

//IPv4对应的是:

struct sockaddr{
	unisgned short as_family;  //协议族
	char sa_data[14];  //IP+端口号
};

同等替换:

struct sockaddr_in{
	sa_family_t sin_family;  /*  协议族 */
	in_port_t sin_port;  /* 端口号 */
	struct in_addr sin_addr;   /* IP地址结构体 */
	unsigned char sin_zero[8];  /* 填充  没有实际意义,只是为跟sockaddr结构体在内存中对齐,这样两者才能相互转换 */
};

IP地址转换API:

inet_aton()函数

功能描述:
把字符串形式的IP地址:“192.168.1.123”转为网络能识别的格式

#include <arpa/inet.h>

头文件:#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
完整描述:
int inet_aton(const char *string, struct in_addr*addr);
参数描述:
1 输入参数string包含ASCII表示的IP地址。
2 输出参数addr是将要用新的IP地址更新的结构。
返回值:
如果这个函数成功,函数的返回值非零,如果输入地址不正确则会返回零。使用这个函数并没有错误码存放在errno中,所以它的值会被忽略。

inet_ntoa()函数

功能描述:
把网络格式的IP地址转为字符串的格式

#include <WINSOCK2.h>
#pragma comment(lib,"WS2_32.LIB")
函数原型: char FAR* PASCAL FAR inet_ntoa( struct in_addr in);
MSDN上本函数的原型描述为:unsigned long inet_addr( __in const char *cp);
in:一个表示Internet主机地址的结构。
注释:
本函数将一个用in参数所表示的Internet地址结构转换成以“.” 间隔的诸如“a.b.c.d”的字符串形式。请注意inet_ntoa()返回的字符串存放在WINDOWS套接口实现所分配的内存中。应用程序不应假设该内存是如何分配的。在同一个线程的下一个WINDOWS套接口调用前,数据将保证是有效。
返回值:
若无错误发生,inet_ntoa()返回一个字符指针。否则的话,返回NULL。其中的数据应在下一个WINDOWS套接口调用前复制出来。

linux:

#include <arpa/inet.h>
char *inet_ntoa(struct in_addr in);

listen()函数

监听

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int listen(int sockfd, int backlog);
参数:
sockfd 一个已绑定未被连接的套接字描述符
backlog 连接请求队列(queue of pending connections)
的最大长度(一般由2到4)。用SOMAXCONN则为系统给出的最大值
返回值:
无错误,返回0,
否则,返回SOCKET ERROR,可以调用函数errno取得错误代码

功能:

  • 设置能处理的最大连接数,listen()并未开始接受连接,只是设置socket的listen模式,listen函数只用于服务器端,服务器进程不知道要与谁连接,因此,它不会主动地要求与某个进程连接,只是一直监听是否有其它客户进程与之连接,然后响应连接请求,并对它做出处理,一个服务进程可以同时处理多个客户进程的连接。主要就两个功能:将一个未连接的套接字转换为一个被动的套接字(监听),规定内核为相应套接字排队的最大连接数。
  • 内核为任何一个给定监听套接字维护两个队列:
    • 未完成连接队列,每个这样的SYN报文段对应其中一项:已有某个客户端发出并到达服务器,而服务器正在等待完成相应的TCP三次握手过程。这些套接字处于SYN_REVD状态;
    • 已完成连接队列,每个已完成TCP三次握手过程的客户端对应其中一项,这些套接字处于ESTABLISHED状态;

参数:

  • sockfd
    sockfd是socket系统调用返回的服务器端socket描述符

  • backlog
    backlog指定在请求对列中允许的最大请求数

accept()函数

链接

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

功能:

  • accept函数由TCP服务器调用,用于从已完成连接队列头返回下一个已完成连接。如果已完成连接队列为空,那么进程被投入睡眠。

参数:

  • sockfd
    sockfd的socket系统调用返回的服务器端socket的描述符
  • addr
    用来返回已连接的对端(客户端)的协议地址
  • addrled
    客户端地址长度

返回值:

  • 该函数的返回值是一个新的套接字描述符,返回值是表示已连接的套接字描述符,而第一个参数是服务器监听套接字描述符。一个服务器通常仅仅创建一个监听套接字,它在该服务器的生命周期内一直存在。内核为每个服务器进程接受的客户连接创建一个已连接套接字(表示TCP三次握手已完成),当服务器完成对某个给定客户的服务时,相应的已连接套接字就会被关闭。

字节流读取函数

在套接字通信中进行字节读取函数:read()、write()。与I/O中的读取函数略有区别,因为它们输入或输出的字节数可能比请求的少。

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);
ssize_t read(int fd, void *buf, size_t count);

/*说明:
*函数均返回:读或写的字节个数,出错则返回-1
*/

第一个将buf中的count个字节写入到文件描述符fd中,成功时返回写入的字节个数。第二个为从fd中读取count个字节到buf中,返回实际所读的字节数。详细应用说明参考使用read,write读到socket(套接字)。

网络I/O还有一些函数,例如:recv() / send(),readv() / writev(),recvmsg() / sendmsg(),recvfrom() / sendto()等。

sand()函数

在TCP套接字上发送数据函数————有链接

#include <sys/types.h>
#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

  • 包含3要素:套接字sockfd,待发送数据buf,数据长度len
  • 函数只能对处于连接状态的套接字使用
  • 参数sockfd为已建立好链接的套接字描述符,即accept函数的返回值
  • 参数buf指向存放待发送数据的缓冲区
  • 参数len为待发送数据的长度
  • 参数flags为控制选项,一般设置为0

recv()函数

在TCP套接字上接收数据函数————有链接

#include <sys/types.h>
#include <sys/socket.h>

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

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

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

  • 包含3要素:套接字sockfd,待接收数据缓冲区buf,数据长度len
  • 函数recv从参数sockfd所指定的套接字描述符(必须是面向连接的套接字)上接收
  • 数据保存到参数buf所指向的数据缓冲区
  • 参数len为缓冲区长度
  • 参数flags为控制选项,一般设置为0

connect()函数

客户端用来连接主机

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

功能:

  • 该函数用于绑定之后的client端(客户端),与服务器建立连接

参数

  • sockfd
    是目的服务器的socket描述符
  • sddr
    是服务器端的IP地址和端口号地址的结构体指针
  • addrlen
    地址长度常被设置为sizeof(struct sockaddr)

返回值:
-成功返回0,遇到错误时返回-1,并且errno中包含相应的错误代码


  1. socket函数参考 ↩︎

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值