一、socket服务器和客户端开发步骤
1、创建套接字socket(),(为后续网络的操作提供一个网络描述符)
2、为套接字添加信息(IP和端口号)
3、监听网络
4、监听到有客户接入,接受一个连接
5、数据交互
6、关闭套接字断开连接
二、具体步骤
服务端
1.指定连接协议(TCP/UDP)
通过 int socket(int domain, int type, int protocol)确认协议
?IPv4为国内常用,IPv6则是国外
2.确认好地址IP和端口号(bind函数)
(1).对bind第二个参数进行替换
对于bind第二个参数进行替换,替换了会更好用一些,使用struct sockaddr_in结构体要强转。想要查看这个结构体声明的地方可以通过指令
cd /usr/include/到该目录下再用grep "struct sockaddr_in {" * -nir指令可以查到定义该结构体的位置意思是在当前目录下用递归的方式寻找,r是递归的意思,n是找出位置行号,i是不区分大小写,调用结果如图
调用成功可以得到一个头文件,184为行号,使用这个结构体时记得包含这个头文件。
(2).端口号配置相关API
配置端口号也需要相应api,因为网络字节序是大端字节序,主机是小端要注意转换,关于字节序转换相关的API
(1)htons(unit16_t host16bityalue);
(2)htonl(unit32_t host32bityalue);
(3)ntohs(uint16_t net16bitvalue);
(4)ntohl(uint32_t net32bitvalue);
(1)(2)返回的是网络字节序的值(3)(4)返回的是主机字节序的值。h代表host,n代表net,s代表short(两个字节),l代表long(4个字节),以上四个函数可以实现主机字节序和网络字节序的转换。
(3).地址配置相关API
地址上传到网路能识别的格式需要用地址转换API
?1、字符串形式地址转网络格式:int inet_aton(coonst char* straddr,struct in_addr *addrp)
starddr字符串形式的IP地址例如“192.168.xxxx”
addrp为实际的地址,编程时使用的是sockaddr_in结构体中的第三个参数的地址即:定义结构体叫struct sockaddr_in s_addr。s_addr为结构体的变量名则该API的第二参数可以写为&s_addr.sin_addr。
2、网络格式IP地址转字符串形式:char* inet_ntoa(struct in_addr inaddr)
struct in_addr sin_addr;//IP地址结构体
3、对于虚拟机的地址可以通过ifconfig指令查询,两地址都可以使用
3.设置监听函数(listen)
?4.连接客户端(accept)
?5.数据的收发
?常用的数据收发除了用read()函数和write()函数之外还可以用send()和recv()区别只是多了一个判断是否阻塞的参数。
6.服务端配置好socket连接通道代码测试
#include <stdio.h>
#include <sys/socket.h>
#include<linux/in.h>
//#include <arpa/inet.h>
#include <sys/socket.h>
#include <stdlib.h>
int main()
{
int s_fd;
//1.socket
s_fd = socket(AF_INET,SOCK_STREAM,0);//确认好协议,建立socket通道,获取一个网络描述符用于后续操作
if(s_fd == -1){//返回值若为-1则建立通道失败
perror("socket");//返回错误信息
exit(-1);//程序退出
}
//使用该结构体struct sockaddr_in *addr代替bind函数原本定义的结构体struct sockaddr *addr
struct sockaddr_in s_addr;
s_addr.sin_family = AF_INET;//确认地址族
s_addr.sin_port = htons(8888);//选择端口号,并转化为网络字节序
inet_aton("192.168.0.200",&s_addr.sin_addr);//将主机的地址字符形式转换为网络形式
//2.bind
// int bind(int sockfd, const struct sockaddr *addr,
// socklen_t addrlen);
bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));//将上面配好的参数放入,对第二个结构体相关参数进行类型转换
//3.listen
listen(s_fd,10);//监听客户端连接最大数量为10
//4.accept
// int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int c_fd = accept(s_fd,NULL,NULL);//接收一个客户端,返回值为一个整形描述符,用于后续对客户端传输内容
//5.read
//6.write
printf("connect\n");//连接成功后进入while循环
while(1);
return 0;
}
该服务器建立在Linux通过Windows模拟另一台设备测试能否连接上服务器,首先在Windows下用打开cmd然后ping一下socket通道配置的地址,该地址可以正常使用就可以用指令telnet 地址 端口号来测试是否能够连接,虚拟机端显示connect表示服务器连接成功。
连接失败可能是地址的问题,注意查看地址是否一致。
客户端
1.建立socket通道
该步骤与服务端第一步相同
2.客户连接主机(connect)
|