tcp通信
# TCP通信流程
# 四次挥手半关闭状态
# server
/* #include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol); 功能:创建一个套接字 参数: domain:协议族 AF_UNIX, AF_LOCAL:本地(进程间通信) AF_INET:ipv4 AF_INET6 :ipv6 type:通信过程中使用的协议类型 SOCK_STREAM:流式协议 SOCK_DGRAM:报式协议 protocol:具体的一个协议,一般写0 SOCK_STREAM:流式协议默认使用TCP SOCK_DGRAM:报式协议默认使用UDP 返回值: 成功:文件描述符 失败:-1 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 功能:绑定ip和端口号 参数: sockfd:通过socket得到的文件描述符 addr:需要绑定的socket地址,封装了IP和端口号的信息 addrlen:第二个参数的大小 返回值: 成功:0 失败:-1 int listen(int sockfd, int backlog); 功能:监听这个sockfd上的连接 参数: sockfd:socket的文件描述符 backlog:max(半连接队列,全连接队列) int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 功能:接收客户端连接,阻塞函数 参数: sockfd:用于监听的文件描述符 addr:传出参数,连接成功后客户端的地址信息 addrlen:第二个参数对应的内存大小 返回值: 成功:用于通信的文件描述符 失败:-1 int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 功能:客户端连接服务器 参数: sockfd:用于通信的文件描述符 addr:客服端要连接服务器的地址信息 addrlen:第二个参数的大小 返回值: 成功:0 失败:-1 */ #include <stdio.h> #include <arpa/inet.h> #include <string.h> #include <stdlib.h> #include <unistd.h> int main() { // 创建socket(用于监听的套接字) int lfd = socket(AF_INET, SOCK_STREAM, 0); if(lfd == -1) { perror("socket"); exit(-1); } // 点分十进制 char buf[] = "192.168.248.128"; int int_ip; // 转int int ret = inet_pton(AF_INET, buf, (void *)&int_ip); if(ret == -1) { perror("inet_pton"); exit(-1); } struct sockaddr_in saddr; saddr.sin_family = AF_INET; // ip saddr.sin_addr.s_addr = int_ip; // 如果指定了0或者INET_ANY则说明可以用以太网ip和无线网ip均可以访问到 // 端口号 saddr.sin_port = htons(9999); ret = bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr)); if(ret == -1) { perror("bind"); exit(-1); } ret = listen(lfd, 5); if(ret == -1) { perror("listen"); exit(-1); } struct sockaddr_in clientaddr; socklen_t len = sizeof(clientaddr); int cfd = accept(lfd, (struct sockaddr *)&clientaddr, &len); if(cfd == -1) { perror("accept"); exit(-1); } // 输出客户端信息 char clientIP[16]; inet_ntop(AF_INET, (void *)&clientaddr.sin_addr.s_addr, clientIP, sizeof(clientIP)); unsigned short clientPORT = ntohs(clientaddr.sin_port); printf("client ip is %s, port is %d\n", clientIP, clientPORT); // 5. 通信 // 读取客户端发送的数据 char recvBuf[1024] = {0}; int recvlen = read(cfd, recvBuf, sizeof(recvBuf)); if(recvlen == -1) { perror("read"); exit(-1); } else if(len == 0) { printf("客户端断开连接······\n"); } else { printf("recv client data: %s\n", recvBuf); } // 给客户端发送数据 char *data = "hello, i am server"; len = write(cfd, data, strlen(data)); if(len == -1) { perror("write"); exit(-1); } // 6. 关闭文件描述符 close(cfd); close(lfd); return 0; }
# client
#include <stdio.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> int main() { int lfd = socket(AF_INET, SOCK_STREAM, 0); if(lfd == -1) { perror("socket"); exit(-1); } char temp[] = "192.168.248.128"; int serverIP; inet_pton(AF_INET, temp, (void *)&serverIP); struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = serverIP; saddr.sin_port = htons(9999); int ret = connect(lfd, (struct sockaddr *)&saddr, sizeof(saddr)); if(ret == -1) { perror("connect"); exit(-1); } char buf[] = "hi, i am client"; write(lfd, buf, strlen(buf)); // 读取客户端发送的数据 char recvBuf[1024] = {0}; int len = read(lfd, recvBuf, sizeof(recvBuf)); if(len == -1) { perror("read"); exit(-1); } else if(len == 0) { printf("服务端断开连接······\n"); } else { printf("recv server data: %s\n", recvBuf); } close(lfd); return 0; }
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。