服务器端客户端编程
一、基本概念和流程
网络编程是计算机科学中一个关键领域,它允许设备之间通过网络进行通信,最常见的网络编程模型是客户端-服务器模型,在这种模型中,服务器是一个等待连接请求的程序,而客户端是发起连接请求的程序,以下是服务器和客户端的基本步骤:
1.服务器端步骤:
创建套接字:使用socket函数创建一个套接字。
绑定地址和端口:初始化服务器地址结构体sockaddr_in,设置IP地址和端口。
监听连接请求:使用listen函数开始监听连接请求,BACKLOG参数指定连接请求队列的最大长度。
接受客户端连接:使用accept函数接受客户端的连接请求,返回一个新的套接字clientSocket,用于与客户端通信。
接收和发送数据:使用recv函数从客户端接收数据,使用send函数向客户端发送数据。
关闭连接:使用close函数关闭连接的套接字。
2.客户端步骤:
创建套接字:使用socket函数创建一个套接字。
设置服务器地址和端口:初始化服务器地址结构体sockaddr_in,设置服务器的IP地址和端口。
连接到服务器:使用connect函数连接到服务器。
发送和接收数据:使用send函数向服务器发送数据,使用recv函数从服务器接收数据。
关闭连接:使用close函数关闭连接的套接字。
二、代码实现
以下是一个简单的C语言示例,展示如何实现TCP服务器和客户端之间的通信。
1.服务器端代码(server.c):
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> void error(const char *msg) { perror(msg); exit(1); } int main(int argc, char *argv[]) { int sockfd, newsockfd, portno; socklen_t clilen; char buffer[256]; struct sockaddr_in serv_addr, cli_addr; int n; if (argc < 2) { fprintf(stderr,"ERROR, no port provided "); exit(1); } sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) error("ERROR on binding"); listen(sockfd,5); clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) error("ERROR on accept"); bzero(buffer,256); n = read(newsockfd,buffer,255); if (n < 0) error("ERROR reading from socket"); printf("Here is the message: %s ",buffer); n = write(newsockfd, "I got your message",18); if (n < 0) error("ERROR writing to socket"); close(newsockfd); close(sockfd); return 0; }
2.客户端代码(client.c):
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> void error(const char *msg) { perror(msg); exit(0); } int main(int argc, char *argv[]) { int sockfd, portno, n; struct sockaddr_in serv_addr; struct hostent *server; char buffer[256]; if (argc < 3) { fprintf(stderr,"usage %s hostname port ", argv[0]); exit(0); } portno = atoi(argv[2]); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); server = gethostbyname(argv[1]); if (server == NULL) { fprintf(stderr,"ERROR, no such host "); exit(0); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) error("ERROR connecting"); printf("Please enter the message: "); bzero(buffer,256); fgets(buffer,255,stdin); n = write(sockfd,buffer,strlen(buffer)); if (n < 0) error("ERROR writing to socket"); bzero(buffer,256); n = read(sockfd,buffer,255); if (n < 0) error("ERROR reading from socket"); printf("%s ",buffer); close(sockfd); return 0; }
三、相关问题与解答栏目
1. 为什么需要三次握手?
答:在TCP协议中,三次握手用于建立可靠的连接,第一次握手时,客户端发送一个SYN包到服务器,请求建立连接,第二次握手时,服务器回应一个SYN-ACK包,确认收到了客户端的请求,第三次握手时,客户端再回应一个ACK包,确认收到了服务器的回应,这个过程确保了双方的接收和发送能力都正常。
问:什么是TCP粘包和拆包问题?如何解决?
答:TCP粘包和拆包问题是指由于TCP流的特性,多个数据包可能会被合并成一个大数据包(粘包),或者一个大数据包被拆分成多个小数据包(拆包),这会导致接收方难以正确解析数据,解决方法包括:消息定长、使用特殊分隔符、将数据长度作为消息头等。
小伙伴们,上文介绍了“服务器端客户端编程”的内容,你了解清楚吗?希望对你有所帮助,任何问题可以给我留言,让我们下期再见吧。
原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/763200.html