简单的客户端程序
今天, 我在写控制小车的上位机程序, 要发送指令给小车的wifi模块, 所以我需要编写客户端程序, 因为wifi模块已配置成了服务器。
客户端要连接服务器, 需要知道服务器的IP地址, 不是它的IPV4的地址, 而是它的默认路由IP, 然后是指定端口号。
IP确定同一网络下的主机位置, 端口号确定主机上我要通信的进程。
知道了关键部分(原理),接下来就是怎么编程了。
***************************************** 图解 ***************************************************
先用Socket创建套接字描述符( 就是ID, 唯一标识网络通信中的端点), 下面是创建套接字的函数说明
int socket ( int domain, int type, int protocol ) (from sys/types.h, sys/socket.h)
domain是 指定通讯的协议名
type是 指定通讯所用到流的类型
protocol 一般都是0, 看手册, 这个当用来指定多个协议时使用
我的是这么写的, socket_fd = socket( AF_INET, SOCK_STREAM, 0 ); // 用IPV4协议, 可靠有序的, 面向连接的数据传输流
成功,返回0, 否则, 返回-1, 并置错。
期间,还要创建一个套接字地址, 把IP,端口号存放在一块儿。下面的这个结构说明
struct sockaddr_in { (from netinet/in.h)
uint8 sin_len;
sa_family sin_family;
in_port_t sin_port; //16位段口号, 网络字节序
struct in_addr sin_addr; //这个IP结构下面解释
char sin_zero [8]; //备用
};
struct in_addr {
in_addr_t s_addr; //32位IP地址, 网络字节序
};
my_addr.sin_family = AF_INET; //IPV4 my_addr.sin_port = htons( 2001 ); //把16位主机号转换位16位网络字节序号 my_addr.sin_addr.s_addr = inet_addr( "192.168.8.1" ); //把字符串转换位32位网络字节序号
然后, 写连接请求。
int connect ( int sockfd, const struct sockaddr *addr, socklen_t addrlen )
sockfd 是套接字描述符
addr 是IP地址结构
addrlen是这个地址结构的大小
注意, 这个IP地址结构类型与前面那个不一样, 这需要转换, 长度还是前面那个的。
代码
fprintf( stdout, "Connecting...\n" ); do{ connect_ret = connect( socket_fd, (struct sockaddr *)&my_addr, sizeof( struct sockaddr_in ) ); }while ( connect_ret != 0 ); fprintf( stdout, "Connected!\n" ); /* 直到返回0 */
说明下, 如果连接成功, 返回0, 否则, 返回-1, 并置错。
到这一步, 就可以与服务器通信了。
如果通信结束, 调用close, 参数还是套接字描述符。