基于TCP的客户端和服务器端的代码设计 您所在的位置:网站首页 tcp协议在客户端和服务器Ubuntu 基于TCP的客户端和服务器端的代码设计

基于TCP的客户端和服务器端的代码设计

2024-07-12 15:38| 来源: 网络整理| 查看: 265

实验平台

linux

实验内容

编写TCP服务器和客户端程序,程序运行时服务器等待客户端连接。一旦连接成功,服务器显示客户端的IP地址和端口号,并向客户端发送字符串

实验原理

TCP是面向连接的通信,其主要实现过程如下:

我们将服务器代码分为两部分。

1. init_tcp_server() tcp服务器的初始化

2. main() 实现读写数据

这样做的好处是main函数不必写的特别冗长,利于维护。从框架上来说,服务器的初始化也与读、写无关。

tcp服务器的初始化----init_tcp_server()

1. 创建socket

sockfd = socket(AF_INET, SOCK_STREAM, 0); //AF_INT:ipv4, SOCK_STREAM:tcp协议

2. 设置socket  当然这一步可以省略

int32_t opt = 1; ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

详细说明:

3. 绑定(bind函数)

将socket和地址(包括ip,port)绑定。需要定义一个结构体地址,以便于将port的主机字节序转化成网络字节序

struct sockaddr_in serveraddr; //地址结构体

bind函数

bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr))

4. listen监听,将接收到的客户端放入队列

listen(sockfd,10) //第二个参数是队列长度

5. 调用accept函数,从队列获取请求,返回socket描述符,如果没有请求(没有客户端连接),将会阻塞,直到获取请求

int fd=accept(sockfd, (struct sockaddr*)&clientaddr, &clientaddr_len);

至此服务器初始化完成,返回成功连接的套接字fd。

服务器端代码如下:tcpserver.c

#include #include #include #include #include #include #include #include #define PORT 1234 #define BACKLOG 10 #define BUFFER_SIZE 100 /** * @brief 初始化tcp服务器 * @param[in] listenfd 监听套接字 * @return -1 - 失败, socket 文件句柄 - 成功 */ int32_t init_tcp_server(int32_t listenfd) { struct sockaddr_in server; struct sockaddr_in client; int32_t connectfd = 0; int32_t addrlen; int32_t ret = 0; addrlen = sizeof(client); /**< 创建一个tcp套接字 */ listenfd = socket(AF_INET, SOCK_STREAM, 0); if (listenfd == -1) { perror("create socket failed!\n"); exit(1); } /**< 设置一个tcp套接字 */ int32_t opt = 1; ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); if (ret < 0) { perror("set socket failed!\n"); exit(1); } /**< 设置服务器监听所有的IP地址 */ bzero(&server, sizeof(struct sockaddr_in)); server.sin_family = AF_INET; server.sin_port = htons(PORT); /**< 主机字节序转化成网络字节序 */ server.sin_addr.s_addr = htonl(INADDR_ANY); /**< 与服务器进行绑定 */ if (bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1) { perror("bind error"); exit(1); } /**< 监听 */ if (listen(listenfd, BACKLOG) == -1) { perror("listen error"); exit(1); } /**< 等待客户端连接,如果没有,一直阻塞 */ if ((connectfd = accept(listenfd, (struct sockaddr *)&client, &addrlen)) == -1) { perror("accept error"); close(listenfd); close(connectfd); exit(1); } printf("You got a connection from client's ip is %s, port is %d\n", inet_ntoa(client.sin_addr), htons(client.sin_port)); return connectfd; } int main() { int32_t listenfd = 0; int32_t connectfd = 0; char buf[BUFFER_SIZE] = "Welcome to my server"; connectfd = init_tcp_server(listenfd); send(connectfd, buf, BUFFER_SIZE, 0); /**< 发送信息到客户端 */ close(connectfd); close(listenfd); } 客户端

同样,将客户端代码分成两部分:

1. init_tcp_client() tcp客户端的初始化

2. main() 实现读写数据

客户端的初始化较为简单,如上图,只要实现socket和connect函数即可。但是我们希望可以手动输入客户端连接的IP地址,便于以后扩展,因此需要给客户端初始化传入一个参数。例如,输入:

./tcpclient 127.0.0.1

客户端代码如下:tcpclient.c

#include #include #include #include #include #include #include #include #define PORT 1234 #define BUFFER_SIZE 100 int32_t init_tcp_client(char *ipaddr) { int sockfd = 0; struct sockaddr_in server; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("create socket failed!\n"); exit(1); } bzero(&server, sizeof(struct sockaddr_in)); server.sin_family = AF_INET; server.sin_port = htons(PORT); inet_pton(AF_INET, ipaddr, &server.sin_addr.s_addr); /**< 点分十进制转换成二进制的网络字节序 */ if (connect(sockfd, (struct sockaddr *)&server, sizeof(server)) == -1) { perror("connect error"); exit(1); } return sockfd; } int32_t main(int argc, char*argv[]) { int32_t sockfd, num; char buf[BUFFER_SIZE]; if (argc != 2) { printf("Usage:%s \n",argv[0]); exit(1); } sockfd = init_tcp_client(argv[1]); if ((num = recv(sockfd, buf, BUFFER_SIZE, 0)) == -1) { perror("recv error"); exit(1); } buf[num - 1] = '\0'; printf("Server Message: %s\n", buf); close(sockfd); return 0; }

Makefile文件如下:

all:server client server:tcpserver.c gcc tcpserver.c -o server client:tcpclient.c gcc tcpclient.c -o client clean: rm -rf server client

实验结果如下:

 

 

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有