使用流式套接字编写一字符界面的通信程序,客户端在与服务器连接成功后,从键盘依次输人若干同学的姓名、学号、性别和考试成绩并发送给服务器端,要求使用结构体调用一次send()函数将同一同学的所有数据项发送到服务器,当输人的姓名为“end”时结束程序;服务器端显示连接成功的客户端的IP地址,然后接收并显示客户端发来的每个同学的姓名、学号、性别、考试成绩,收到“end"后结束。
时间: 2024-03-14 14:43:41 浏览: 123
基于tcp,编写基于流式套接字的通信程序。
好的,我会尽力回答你的问题。首先,需要明确的是,流式套接字是一种传输层协议,用于在网络上提供数据传输服务,客户端和服务器通过套接字进行通信。在C语言中,可以使用socket库提供的函数来实现流式套接字的编程。
下面是一个基本的流式套接字客户端程序,可以用来发送数据给服务器:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
struct student {
char name[20];
char id[10];
char gender[4];
float score;
};
int main() {
struct sockaddr_in server_addr;
int sockfd, ret;
char buffer[1024];
struct student stu;
// 创建套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
// 设置服务器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
// 连接服务器
ret = connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (ret == -1) {
perror("connect");
exit(EXIT_FAILURE);
}
// 从键盘输入学生信息并发送给服务器
while (1) {
printf("请输入学生姓名(输入end结束):");
scanf("%s", stu.name);
if (strcmp(stu.name, "end") == 0) {
break;
}
printf("请输入学号:");
scanf("%s", stu.id);
printf("请输入性别:");
scanf("%s", stu.gender);
printf("请输入考试成绩:");
scanf("%f", &stu.score);
// 将学生信息打包成结构体发送给服务器
ret = send(sockfd, &stu, sizeof(stu), 0);
if (ret == -1) {
perror("send");
exit(EXIT_FAILURE);
}
}
// 关闭套接字
close(sockfd);
return 0;
}
```
这是一个简单的客户端程序,可以从键盘输入学生信息,并将其打包成结构体发送给服务器。需要注意的是,在发送数据时,使用了send函数一次性将结构体的所有数据项发送到服务器。
接下来是一个基本的流式套接字服务器程序,可以用来接收客户端发送的数据,并将其显示出来:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_PORT 8080
struct student {
char name[20];
char id[10];
char gender[4];
float score;
};
int main() {
struct sockaddr_in server_addr, client_addr;
int sockfd, newsockfd, ret;
socklen_t client_len;
char buffer[1024];
struct student stu;
// 创建套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
// 设置服务器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
// 绑定套接字
ret = bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (ret == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
// 监听套接字
ret = listen(sockfd, 10);
if (ret == -1) {
perror("listen");
exit(EXIT_FAILURE);
}
// 接受客户端连接并显示客户端IP地址
client_len = sizeof(client_addr);
newsockfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_len);
if (newsockfd == -1) {
perror("accept");
exit(EXIT_FAILURE);
}
printf("客户端 %s 连接成功!\n", inet_ntoa(client_addr.sin_addr));
// 接收客户端发送的学生信息并显示
while (1) {
ret = recv(newsockfd, &stu, sizeof(stu), 0);
if (ret == -1) {
perror("recv");
exit(EXIT_FAILURE);
} else if (ret == 0) {
break;
}
printf("姓名:%s,学号:%s,性别:%s,成绩:%.2f\n",
stu.name, stu.id, stu.gender, stu.score);
}
// 关闭套接字
close(newsockfd);
close(sockfd);
return 0;
}
```
这是一个简单的服务器程序,可以接收客户端发送的学生信息,并将其显示出来。需要注意的是,在接收数据时,使用了recv函数一次性接收了结构体的所有数据项。
需要注意的是,在编写流式套接字程序时,需要注意字节序的问题。因为不同机器的字节序可能不同,在发送和接收数据时,需要进行字节序的转换。可以使用htonl和ntohl函数进行字节序的转换。
阅读全文