用C语言分别编写TCP客户端和客户端程序段 ,要求: 1. 已知服务器的域名,获取服务器IP地址,向服务器发出连接请求; 2. 连接成功后,发送客户端本地主机名和学生本人学号到服务器端。客户端接收回复数据,并进行判断。若回复包含“OK”,则客户端显示“登录成功”;否则,客户端显示“登录失败”。
时间: 2023-12-30 17:06:16 浏览: 75
在C的TCP客户端和服务器套接字的实现
好的,我可以为您提供一些参考代码,但请注意,以下代码仅供参考,具体实现可能需要根据您的具体需求进行调整。
TCP客户端代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define PORT "12345" // 服务器端口号
#define MAXDATASIZE 100 // 最大数据长度
int main(int argc, char *argv[]) {
int sockfd, numbytes;
char buf[MAXDATASIZE];
struct addrinfo hints, *servinfo, *p;
int rv;
char s[INET_ADDRSTRLEN];
if (argc != 2) {
fprintf(stderr,"usage: client hostname\n");
exit(1);
}
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("client: socket");
continue;
}
if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("client: connect");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "client: failed to connect\n");
return 2;
}
inet_ntop(p->ai_family, &(((struct sockaddr_in*)p->ai_addr)->sin_addr), s, sizeof s);
printf("client: connecting to %s\n", s);
freeaddrinfo(servinfo);
// 发送数据
char hostname[MAXDATASIZE];
char student_id[MAXDATASIZE];
printf("Please input hostname and student id:\n");
scanf("%s%s", hostname, student_id);
char send_data[MAXDATASIZE];
strcpy(send_data, hostname);
strcat(send_data, " ");
strcat(send_data, student_id);
if (send(sockfd, send_data, strlen(send_data), 0) == -1) {
perror("send");
close(sockfd);
exit(1);
}
// 接收数据
if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
perror("recv");
exit(1);
}
buf[numbytes] = '\0';
printf("client: received '%s'\n",buf);
// 判断登录是否成功
if (strstr(buf, "OK") != NULL) {
printf("Login succeeded!\n");
} else {
printf("Login failed!\n");
}
close(sockfd);
return 0;
}
```
TCP服务器端代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netdb.h>
#define PORT "12345" // 服务器端口号
#define BACKLOG 10 // 最大连接数
#define MAXDATASIZE 100 // 最大数据长度
void *get_in_addr(struct sockaddr *sa) {
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main() {
int sockfd, new_fd;
struct addrinfo hints, *servinfo, *p;
struct sockaddr_storage their_addr;
socklen_t sin_size;
char s[INET6_ADDRSTRLEN];
int yes=1;
char buf[MAXDATASIZE];
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("server: socket");
continue;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("server: bind");
continue;
}
break;
}
freeaddrinfo(servinfo);
if (p == NULL) {
fprintf(stderr, "server: failed to bind\n");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
printf("server: waiting for connections...\n");
while(1) {
sin_size = sizeof their_addr;
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
if (new_fd == -1) {
perror("accept");
continue;
}
inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s);
printf("server: got connection from %s\n", s);
if (!fork()) {
close(sockfd);
// 接收数据
if (recv(new_fd, buf, MAXDATASIZE-1, 0) == -1) {
perror("recv");
exit(1);
}
buf[MAXDATASIZE-1] = '\0';
printf("server: received '%s'\n", buf);
// 判断登录是否成功
if (strstr(buf, "localhost") != NULL && strstr(buf, "123456") != NULL) {
if (send(new_fd, "OK", 2, 0) == -1) {
perror("send");
}
} else {
if (send(new_fd, "FAIL", 4, 0) == -1) {
perror("send");
}
}
close(new_fd);
exit(0);
}
close(new_fd);
}
return 0;
}
```
这份代码实现了基本的需求,但仍有许多可以改进的地方,例如错误处理、输入校验等等。
阅读全文