一、题目
用标准C编写linux系统下的基于socket通信的TCP服务器与客户机的一对一的一问一答的聊天程序。
要求:
1、 编写出服务器程序,并命名为tcp_server.c.
2、 编写出客户端程序,并命名为tcp_client.c.
3、 以客户机发送字符串BeginChat开始聊天,发送字符串QuitChat退出聊天并结束两边的程序。
4、 聊天的内容都由键盘输入。
二、程序
tcp_server.c
#include
#include
#include
#include <string.h>
#include
#include
#includein.h>
#include
#define server_port 3456
#define BACKLOG 10
#define MAX_SIZE 1024
void SendMsg(int to_sockfd, char *msg); // 发送消息
char *RecvMsg(int from_sockfd); // 接收消息
int main()
{
struct sockaddr_in server_addr,client_addr;
int addr_len = sizeof(struct sockaddr_in);
int server_fd, client_fd;
// 初始化服务端sockaddr_in结构体
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //或者 = INADDR_ANY
bzero(&(server_addr.sin_zero),8);
// 创建一个socket
server_fd = socket(AF_INET, SOCK_STREAM,0);
if(server_fd == -1){
perror("socket error");
exit(-1);
}
// 绑定套接字
int bind_stats = bind(server_fd,(struct sockaddr *)&server_addr,addr_len);
if(bind_stats == -1){
perror("bind error");
exit(-1);
}
// 侦听
if((listen(server_fd, BACKLOG))==-1){
perror("listen error");
exit(-1);
}
// 循环等待客户端连接
while(1)
{
// 获取连接
client_fd = accept(server_fd,(struct sockaddr *)&client_addr,&addr_len);
if(client_fd == -1)
{
perror("accept error");
}
printf("Server get connection from %s\n",inet_ntoa(client_addr.sin_addr));
SendMsg(client_fd,"connected");
char chat_msg[MAX_SIZE]; // 存储信息
char reply_msg[MAX_SIZE]; // 回复信息
bzero(chat_msg,MAX_SIZE);
/*int byte_num = recv(client_fd,chat_msg,MAX_SIZE,0); // 获取接收到的字符数
chat_msg[byte_num] = '\0'; // 收尾字符串*/
strcpy(chat_msg, RecvMsg(client_fd));
if(strcmp(chat_msg,"BeginChat") == 0) // 当接收到‘BeginChat’时开始聊天
{
printf("Client begin chat\n");
SendMsg(client_fd,"ok, chat begin\n");
// 一问一答模式
while(1)
{
bzero(chat_msg,MAX_SIZE);
strcpy(chat_msg ,RecvMsg(client_fd)); // 接收信息
if(strcmp(chat_msg,"QuitChat") == 0)
{
printf("Client LogOff\n");
break;
}
printf("client said: %s\n",chat_msg); // 显示接收到信息
printf("me:");
scanf("%s",reply_msg); // 填写回复到信息
SendMsg(client_fd,reply_msg); // 发送回复信息
}
close(client_fd);
}
}
return 0;
}
// 发送消息函数
void SendMsg(int to_sockfd, char *msg)
{
int len = strlen(msg);
if(send(to_sockfd,msg,MAX_SIZE,0)==-1){
perror("send error");
}
}
// 接收消息
char *RecvMsg(int from_sockfd)
{
char msg[MAX_SIZE];
bzero(msg,MAX_SIZE);
int byte_num = recv(from_sockfd,msg,MAX_SIZE,0);
msg[byte_num] = '\0';
return msg;
}
tcp_client.c
#include
#include
#include
#include <string.h>
#include
#include
#includein.h>
#include
#define dest_port 3456
#define dest_IP "127.0.0.1"
#define MAX_SIZE 1024
void SendMsg(int to_sockfd, char *msg); // 发送消息
char *RecvMsg(int from_sockfd); // 接收消息
int main()
{
struct sockaddr_in server_addr;
int addr_len = sizeof(struct sockaddr_in);
int server_fd, client_fd;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(dest_port);
server_addr.sin_addr.s_addr = inet_addr(dest_IP);
bzero(&(server_addr.sin_zero),8);
server_fd = socket(AF_INET,SOCK_STREAM,0);
if(connect(server_fd,(struct sockaddr *)&server_addr,addr_len) == 0)
{
char chat_msg[MAX_SIZE]; // 存储信息
bzero(chat_msg,MAX_SIZE);
strcpy(chat_msg , RecvMsg(server_fd));
if(strcmp(chat_msg,"connected") == 0)
{
printf("%s\n",chat_msg);
while(1)
{
printf("me:");
scanf("%s",chat_msg); // 填写信息
SendMsg(server_fd,chat_msg); // 发送信息
if(strcmp(chat_msg,"QuitChat") == 0)
{
printf("EndChat\n");
break;
}
bzero(chat_msg,MAX_SIZE);
strcpy(chat_msg , RecvMsg(server_fd)); // 接收消息
printf("server reply:%s\n",chat_msg);
}
}
close(server_fd);
}
return 0;
}
// 发送消息函数
void SendMsg(int to_sockfd, char *msg)
{
int len = strlen(msg);
if(send(to_sockfd,msg,MAX_SIZE,0)==-1){
perror("send error");
}
}
// 接收消息
char *RecvMsg(int from_sockfd)
{
char msg[MAX_SIZE];
bzero(msg,MAX_SIZE);
int byte_num = recv(from_sockfd,msg,MAX_SIZE,0);
msg[byte_num] = '\0';
return msg;
}