TCP通信:有连接的数据流传输协议。
特点:可靠稳定,但速度慢,效率低,资源消耗大。(点到点)
应用场合:浏览器,文件传输。
本文借鉴点击查看 网络编程 (传输层 -- TCP协议)
TCP的三次握手和四次挥手:
三次握手:1.client端向server端发送请求;
2.server端收到请求,回复client端并分配资源;
3.client端收到回复并分配资源。
四次挥手:1.client端向server端发送中断请求;
2.server端收到请求,如果还有数据没有传输完成,则回复client端ACK报文,client端进入等待状态;
3.server端数据传输完成,向client端发送FIN报文;
4.client端收到报文,向server端发送结束报文,server端关闭,client端等待2MSL后,未收到回复,关闭断开连接
//client客户端
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <arpa/inet.h>
//client客户端
int main (int argc, char **argv)
{
printf("输入puit 结束通信\n");
if(argc != 3)
{
printf("需要:%s, ip地址\n ", argv[0]);
exit(1);
}
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in local;
local.sin_family = AF_INET;
inet_pton(AF_INET, argv[1], &local.sin_addr);
// local.sin_addr.s_addr = inet_addr(argv[1]);
local.sin_port = htons(atoi(argv[2]));
int ret = connect(sock, (struct sockaddr*)&local, sizeof(local));
if(ret < 0)
{
printf("connect error\n");
exit(1);
}
printf("connect success\n");
while(1)
{
char buf[1024] = {0};
printf("client#");
fflush(stdout);
ssize_t s = read(0, buf, sizeof(buf));
if(s > 0)
{
buf[s-1] = 0;
write(sock, buf, sizeof(buf));
if(strcmp(buf, "quit")== 0)
{
printf("client quit\n");
break;
}
read(sock, buf, sizeof(buf));
printf("server# %s\n", buf);
}
}
close(sock);
return 0;
}
服务端
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
int startup(char* ip, int port)
{
int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
printf("创建套接字错误create socket error\n");
exit(1);
}
struct sockaddr_in server_socket;
server_socket.sin_family = AF_INET;
server_socket.sin_port = htons(port);
server_socket.sin_addr.s_addr = inet_addr(ip);
if(bind(sock, (struct sockaddr*)&server_socket, sizeof(struct sockaddr_in)) < 0)
{
printf("bind error\n");
exit(2);
}
if(listen(sock, 5) < 0)
{
printf("listen error\n");
close(sock);
exit(3);
}
printf("bind and listen success\n");
return sock;
}
void service(int sock, char *ip, int port)
{
while(1)
{
char buf[1024] = {0};
ssize_t s = read(sock, buf, sizeof(buf));
if(s < 0)
{
perror("error read");
exit(1);
}else if(s > 0)
{
buf[s-1] = 0;
if(strcmp(buf, "puit")==0)
{
printf("client puit...\n");
break;
}
printf("client[%s ip][%d port]:%s\n", ip, (port), buf);
write(sock, buf, sizeof(buf));
}else
{
printf("client puit(离开)..\n");
close(sock);
break;
}
}
printf("connect end ...Please wait...连接结束\n");
}
int main (int argc, char** argv)
{
if(argc != 3)
{
printf("需要:%s ip地址 port端口\n", argv[0]);
exit(1);
}
int listen_sock = startup(argv[1], atoi(argv[2]));//监听套接字
struct sockaddr_in peer;//接受客户端地址和端口号
for(;;)
{
socklen_t len = sizeof(peer);
int new_sock = accept(listen_sock, (struct sockaddr*)&peer, &len);//接受连接
if(new_sock < 0)
{
printf("connect error 连接失败\n");
continue;
}
char buf[32];
memset(buf, 0, sizeof(buf));
inet_ntop(AF_INET, &peer.sin_addr, buf, sizeof(buf));
printf("connect success, ip is:%s, port is:%d\n", buf, (ntohs(peer.sin_port)));
service(new_sock, buf, ntohs(peer.sin_port));//服务器端执行操作
close(new_sock);
}
close(listen_sock);
return 0;
}