写了一个简单的服务器软件,但是没有写客户端。现在我将客户端实现了,其实昨天已经说了客户端的实现步骤了。
步骤:
- socket()
- 初始化
- connet()链接
- 从标准输入读数据fgets()
- 传数据到服务器write()
- 读从服务器返回的数据read()
- 写数据到屏幕上write()
- 关闭socket文件close()
都没有什么新知识的。所以我也就直接贴代码了;
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define ADDR_POST 9527
int main(void)
{
int c_fd; //客户端的socket文件描述符
int len; //从服务器传回的字符串长度
char buf[BUFSIZ]; //储存数据
struct sockaddr_in clie_addr; //客户端地址结构体
socklen_t addr_len; //客户端地址结构体大小
//创建客户端socket文件,指定IPV4 ,TCP协议
c_fd = socket(AF_INET,SOCK_STREAM,0);
//初始化客户端地址结构体
inet_pton(AF_INET, "127.0.0.1", &clie_addr.sin_addr.s_addr);//将IP字符串转化为网络值存入其中,这个"127.0.0.1"就是客户端的IP,但不一定是公网IP
clie_addr.sin_family = AF_INET;//指定IPV4协议族
clie_addr.sin_port = htons(ADDR_POST);//将服务器的端口转化为网络值存入
connect(c_fd, (struct sockaddr*)&clie_addr, sizeof(clie_addr));//由地址结构体连接服务器;
//因为地址结构体中有服务器的端口,端口在机器上是唯一的。
//刚接触,其实有很多还是不大明白。我们的服务器软件和客户端软件都是运行在一台机器上的,一台机器中的端口号是唯一的,类似进程号。至于若是服务器软件和客户端位于不同的机器是怎么经过网络找到对应的机器,我就不大清楚了,以后学到了在解惑吧。
while (1)
{
fgets(buf, sizeof(buf), stdin); //从标准输入中读取数据
write(c_fd, buf, strlen(buf)); //写到服务器中c_fd既有接收端又有发送端。
len = read(c_fd, buf, sizeof(buf)); //读从服务器返回的数据
write(STDOUT_FILENO, buf, len); //写到屏幕上
}
close(c_fd);
return 0;
}
其实很简单的。
结果和昨天的示例一样:。服务器依然是阻塞着的,没啥好看的。
由于客户端不需要固定的端口号,因此不必调用bind(),客户端的端口号由内核自动分配。注意,客户端不是不允许调用bind(),只是没有必要调用bind()固定一个端口号,服务器也不是必须调用bind(),但如果服务器不调用bind(),内核会自动给服务器分配监听端口,每次启动服务器时端口号都不一样,客户端要连接服务器就会遇到麻烦。
客户端和服务器启动后可以使用netstat命令查看链接情况:
netstat -apn|grep 6666