一、实验目的
1、了解网络编程概念,了解套接字编程相关技术;
2、掌握socket编程相关函数功能,使用方法;
3、掌握socket编程基本流程及方法。
二、实验环境:
一台运行GNOME图形用户界面的任意一种Linux操作系统的计算机。
PART 1 程序理解 (socket实现服务器端-客户端的TCP通信)
- 建立一个服务器端程序server.c,代码如下:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SERVER_PORT 6000 //端口号可自己设置
#define SERVER_IP "192.168.126.128" // IP 地址请自己根据实际情况设置
int listen_fd = -1;
void signal_handler(int arg)
{
printf("close listen_fd(signal = %d)\n", arg);
close(listen_fd);
exit(0);
}
int main(int argc, const char *argv[])
{
int new_fd = -1;
struct sockaddr_in server;
struct sockaddr_in client;
socklen_t saddrlen = sizeof(server);
socklen_t caddrlen = sizeof(client);
signal(SIGINT, signal_handler);
memset(&server, 0, sizeof(server));
memset(&client, 0, sizeof(client));
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0)
{
printf("socket error!\n");
return -1;
}
server.sin_family = AF_INET;
server.sin_port = htons(SERVER_PORT);
server.sin_addr.s_addr = inet_addr(SERVER_IP);
if (bind(listen_fd, (struct sockaddr *)&server, saddrlen) < 0)
{
printf("bind error!\n");
return -1;
}
if (listen(listen_fd, 5) < 0)
{
printf("listen error!\n");
return -1;
}
char rbuf[256] = {0};
int read_size = 0;
while (1)
{
new_fd = accept(listen_fd, (struct sockaddr *)&client, &caddrlen);
if (new_fd < 0)
{
perror("accept");
return -1;
}
printf("new client connected.IP:%s,port:%u\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
while (1)
{
read_size = read(new_fd, rbuf, sizeof(rbuf));
if (read_size < 0)
{
printf("read error!\n");
continue;
}
else if (read_size == 0)
{
printf("client (%d) is closed!\n", new_fd);
close(new_fd);
break;
}
printf("recv:%s\n", rbuf);
}
}
close(listen_fd);
return 0;
}

- 建立一个客户端程序client.c,代码如下:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SERVER_PORT 6000 // 端口
#define SERVER_IP "192.168.126.128" //服务器IP地址
int main(int argc, const char *argv[])
{
int connect_fd = -1;
struct sockaddr_in server;
socklen_t saddrlen = sizeof(server);
memset(&server, 0, sizeof(server));
connect_fd = socket(AF_INET, SOCK_STREAM, 0);
if (connect_fd < 0)
{
printf("socket error!\n");
return -1;
}
server.sin_family = AF_INET;
server.sin_port = htons(SERVER_PORT);
server.sin_addr.s_addr = inet_addr(SERVER_IP);
if (connect(connect_fd, (struct sockaddr *)&server, saddrlen) < 0)
{
printf("connect failed!\n");
return -1;
}
char buf[256] = {0};
while (1)
{
printf(">");
fgets(buf, sizeof(buf), stdin);
if (strcmp(buf, "quit\n") == 0)
{
printf("client will quit!\n");
break;
}
write(connect_fd, buf, sizeof(buf));
}
close(connect_fd);
return 0;
}

3.编译以上程序,在一个终端窗口中运行server程序,另外打开一个终端窗口,运行client程序。观察程序运行结果。

4.打开第3个终端窗口,运行client窗口,观察程序运行结果。分析:服务器端能同时响应两个客户端的连接请求吗?

PART 2 程序实现
PART 1 中实现的功能是客户端向服务器端发送信息,服务器端接收到信息后显示出来,在理解上述程序的基础上,对程序功能进行扩展,实现如下功能:
(1)服务器端接收到信息后,进行简单的加密处理,然后将加密之后的字符串发回给客户端,客户端将其显示出来。 加密策略为:如果字符为英文字符,则进行大小写转换,如果是数字字符,则将相应的数字加6再取个位数,如果是其他字符,则保留原样。如服务器接收到的字符串为:A1b2D9#6,则加密之后的字符串为:a7B8d5#2
(2)如果服务器端接收的字符串是"time",则不需要进行加密,而是将系统时间发送给客户端,客户端显示收到的信息。

PART 3 扩展部分
使用socket编程实现一个一对一的聊天程序,(以TCP方式通信)基本功能包括:
(1)双方一对一接收,发送文本信息。
(2)将聊天信息记录以文本文件的形式保存在服务器端中,下次登录时,可以显示出前面50条聊天信息。
本文介绍了如何通过套接字编程实现服务器端与客户端的TCP通信,包括基础的服务器与客户端交互,并演示了如何对接收到的信息进行加密处理以及扩展至一对一聊天程序,记录聊天历史的功能。
1528

被折叠的 条评论
为什么被折叠?



