c语言实现tcp网络通信,客户端显示连接成功后服务端返回要求客户端登录,客户端显示“Please enter user and pw”客户端输入账号密码(正确的应为 abc 和 def),服务端返回登录成功,否则显示登陆失败(密码错误)
时间: 2023-05-28 19:01:56 浏览: 91
服务端代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8888
#define MAXLINE 1024
int main() {
int listenfd, connfd;
struct sockaddr_in servaddr, cliaddr;
char buff[MAXLINE];
char account[MAXLINE] = "abc";
char password[MAXLINE] = "def";
socklen_t len;
pid_t pid;
// 创建套接字
listenfd = socket(AF_INET, SOCK_STREAM, 0);
// 初始化地址结构
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
// 绑定地址和端口
bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
// 监听连接
listen(listenfd, 5);
printf("Server is listening at port %d...\n", PORT);
while (1) {
len = sizeof(cliaddr);
// 接受客户端连接
connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &len);
// 创建子进程处理客户请求
pid = fork();
if (pid == -1) {
printf("Create fork error\n");
exit(1);
}
else if (pid == 0) { // child process
printf("Client connected from %s:%d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
// 连接成功后要求客户端登录
strcpy(buff, "Please enter user and pw");
send(connfd, buff, strlen(buff), 0);
// 处理客户端传来的帐号密码
bzero(buff, sizeof(buff));
recv(connfd, buff, MAXLINE, 0);
char* ptr = strtok(buff, " ");
char* user = ptr;
ptr = strtok(NULL, "\n");
char* pw = ptr;
// 校验帐号密码
if (strcmp(user, account) == 0 && strcmp(pw, password) == 0) {
strcpy(buff, "Login success");
}
else {
strcpy(buff, "Login failed (wrong password)");
}
// 返回登录结果
send(connfd, buff, strlen(buff), 0);
// 关闭连接
close(connfd);
printf("Client disconnected\n");
exit(0);
}
// 父进程关闭连接
close(connfd);
}
return 0;
}
```
客户端代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERV_PORT 8888
#define MAXLINE 1024
int main(int argc, char *argv[]) {
int sockfd;
struct sockaddr_in servaddr;
char buff[MAXLINE];
// 创建套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
// 初始化地址结构
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
// 将点分十进制IP地址转换为网络字节序IP地址
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
// 连接服务器
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
printf("Connect error\n");
exit(1);
}
// 接受服务器的要求登录信息
bzero(buff, sizeof(buff));
recv(sockfd, buff, MAXLINE, 0);
printf("%s\n", buff);
// 输入帐号密码
printf("Please enter user and pw: ");
fgets(buff, MAXLINE, stdin);
// 发送帐号密码给服务器
send(sockfd, buff, strlen(buff), 0);
// 接受服务器的登录结果
bzero(buff, sizeof(buff));
recv(sockfd, buff, MAXLINE, 0);
// 显示登录结果
printf("%s\n", buff);
// 关闭连接
close(sockfd);
return 0;
}
```
参考资料:
- [TCP/IP网络编程套接字API](https://blog.csdn.net/Wayne_Wang/article/details/52)
- [TCP网络通信之C/S模型(C实现,在linux环境下)](https://blog.csdn.net/qq_37342943/article/details/81505805)
阅读全文