SOCKET:
在计算机通信领域,socket 被翻译为“套接字”即(端口+地址),它是计算机之间进行通信的一种约定或一种方式。通过 socket这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据 socket起源于unix,而unix下“一切皆文件”,都可以用“打开open –> 读写write/read关闭close”模式来操作。
TCP:
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP_socket通信流程:
服务端:
创建socket绑定主机的端口号及IP地址监听是否有客户端请求接入接受连接请求数据传输通信关闭socket
客户端:
创建socket设置对方的ip地址及端口号发起连接请求数据传输通信关闭socket
以下是我理解的通信流程:
就像两个人间的线上交流,前提是双方都先要注册自己的账号(创建socket),而建立交流时总会有被动或主动的一方;
被动方就像时服务器:你可以说他内向又渴望交流,注册号账号后就把自己的账号和自己公开信息结合了(绑定),在没有事做时他就在那等别人加他好友(监听),他看到后同意就建立了连接(接收连接请求),最后聊完了就下线(关闭socket);
主动方就像客户端:想要和被动那方说什么时,就需要查找搜索对方的账号(设置对方IP和端口),点击添加好友(发起连接请求)这一步当然不一定100%通过,也许就会出现什么特殊情况,对方同意后就可以正常交流,聊完下线(关闭socket)。
流程实现:
1.服务端查看自己的ip地址
在命令行输入ifconfig
这个inet就是服务端需要绑定的ip。
2.需要用到的相关函数
创建socket
int socket(int domain, int type, int protocol);
发起连接
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
绑定
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
监听
int listen(int sockfd, int backlog);
接受连接
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
发送/接受数据(因为Linux下一切皆文件,使用write/read也可以)
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
3.服务端的建立
int tcp_socket(const char *ip, int port)
{
//创建socket
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if(-1 == socket_fd)
{
perror("create socket error");
return -1;
}
printf("socket创建成功\n");
//设置主机端口及ip地址
struct sockaddr_in server;
memset(&server,'\0',sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(ip);
//绑定ip地址及端口
if(bind(socket_fd,(struct sockaddr *)&server,sizeof(server)) < 0)
{
perror("bind error");
return -1;
}
printf("bind ok\n");
//监听是否有人连接 最大连接数5
if(listen(socket_fd,5) < 0)
{
perror("listen error");
return -1;
}
printf("listen ok\n");
return socket_fd;
}
4.客户端的建立
int tcp_socket(const char *ip, int port)
{
//创建socket ipv4 流式套接字(tcp)
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if(-1 == socket_fd)
{
perror("create socket error");
return -1;
}
printf("socket创建成功\n");
//指定服务端的端口及ip地址
struct sockaddr_in server;
memset(&server,'\0',sizeof(server));
server.sin_family = AF_INET; //使用的通信协议
server.sin_port = htons(port); //端口号
server.sin_addr.s_addr = inet_addr(ip); //ip地址
//向指定ip端口的服务器发起连接请求
if(connect(socket_fd, (struct sockaddr *)&server, sizeof(server)) < 0)
{
perror("connect error");
return -1;
}
printf("发起连接请求\n");
return socket_fd;
}
5.数据通信
服务端
int main()
{
int socket_fd = tcp_socket("192.168.139.138",6666);
if(socket_fd < 0)
{
return -1;
}
//接受连接
struct sockaddr_in client;
int len = sizeof(client);
int new_fd = accept(socket_fd,(struct sockaddr *)&client,&len);
if(new_fd < 0)
{
perror("accept error");
return -1;
}
printf("accept ok\n");
printf("ip = %s\tport = %d\n",inet_ntoa(client.sin_addr),client.sin_port);
//数据传输
char buf[20] = {'\0'};
recv(new_fd,buf,sizeof(buf),0);
printf("接收到的数据为:%s",buf);
return 0;
}
客户端
int main()
{
//通信的建立
int socket_fd = tcp_socket("192.168.139.138",6666);
if(socket_fd < 0)
{
return -1;
}
//数据发送/接受
char buf[20] = {'\0'};
printf("请输入要发送的数据:");
fgets(buf,sizeof(buf),stdin);
send(socket_fd,buf,sizeof(buf),0);
//关闭socket
close(socket_fd);
}
运行结果
我这是自己和自己玩,若要和别人的主机通信仅需修改封装好的tcp_socket()的参数即可。
以上若有错误,请大佬指出。
参考文章
发表评论