为了更深刻的锻炼认识TCP/IP协议,加强自己对Linux系统的网络编程部分的编写代码能力,编写基于控制台的聊天窗口,用本机既当服务器又当客户端,先打开一个shell,运行服务器程序,然后再打开一个shell窗口,运行客户端程序,显示连接成功,开始聊天吧。不知道为什么上传效果图不成功,把图放在相册了。
/*客户端*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define BUFFER_SIZE 256
#define PORT 4568
char recv_buff[BUFFER_SIZE];
char send_buff[BUFFER_SIZE];
int main(void)
{
char write_flag=0;
char read_flag=1;
int sockfd;// 套结字
struct sockaddr_in cli_addr;//服务器的IPv4的套结字结构
if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)//创建套结字
{
perror("socket");
exit(1);
}
else
{
printf("creat client socket success id:%d\n",sockfd);
}
bzero(&cli_addr,sizeof(struct sockaddr_in));
cli_addr.sin_family=AF_INET;
cli_addr.sin_port=htons(PORT);
cli_addr.sin_addr.s_addr=htonl(INADDR_ANY);
if(connect(sockfd,(struct sockaddr*)(&cli_addr),sizeof(struct sockaddr))<0)
{
perror("connect");
exit(2);
}
else
{
printf("connect server success.\n");
}
memset(send_buff,0x00,sizeof(send_buff));
memset(recv_buff,0x00,sizeof(send_buff));
while(1)
{
if(strlen(send_buff)==0&&write_flag==1)//判断发送缓冲区是否为空
{
gets(send_buff);
if(write(sockfd,send_buff,strlen(send_buff))<0)
{
perror("write");
exit(3);
}
else
{
printf("Client:\n");
printf(" %s\n",send_buff);
}
read_flag=1;
write_flag=0;
memset(recv_buff,0x00,strlen(recv_buff));
}
else if(strlen(recv_buff)==0&&read_flag==1)
{
if(read(sockfd,recv_buff,sizeof(recv_buff))<0)
{
perror("read");
exit(4);
}
else if(strlen(recv_buff)>0)
{
printf("server:\n");
printf(" : %s\n",recv_buff);
memset(send_buff,0x00,strlen(send_buff));//接受到数据后清空发送缓冲区
write_flag=1;
read_flag=0;
}
}
}
printf("end.\n");
close(sockfd);
return 0;
}
/*服务器*/
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define BUFFER_SIZE 256
#define PORT 4568
char recv_buff[BUFFER_SIZE];
char send_buff[BUFFER_SIZE];
int main(void)
{
char write_flag=0;
char read_flag=1;
int sockfd,newsockfd;// 套结字
socklen_t addr_len;
struct sockaddr_in ser_addr;//服务器的IPv4的套结字结构
addr_len=sizeof(struct sockaddr_in);
if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)//创建套结字
{
perror("socket");
exit(1);
}
else
{
printf("creat socket success id:%d\n",sockfd);
}
bzero(&ser_addr,sizeof(struct sockaddr_in));
ser_addr.sin_family=AF_INET;
ser_addr.sin_port=htons(PORT);
ser_addr.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(sockfd,(struct sockaddr *)(&ser_addr),sizeof(struct sockaddr))<0)//绑定
{
perror("bind");
exit(2);
}
else
{
printf("bind success.\n");
}
if(listen(sockfd,10)<0)//最多允许10个客户端进程请求,监听
{
perror("listen");
exit(3);
}
else
{
printf("listening.....\n");
}
memset(send_buff,0x00,sizeof(send_buff));
memset(recv_buff,0x00,sizeof(send_buff));
if((newsockfd=accept(sockfd,(struct sockaddr*)(&ser_addr),&addr_len))<0)
{
//accept函数使用错误注意复习
perror("accept");
exit(4);
}
else
{
printf("connect success.\n");
}
write(newsockfd,"have connect!",strlen("have connect"));
while(1)
{
if(strlen(send_buff)==0&&write_flag==1)//判断发送缓冲区是否为空
{
gets(send_buff);
if(write(newsockfd,send_buff,strlen(send_buff))<0)
{
perror("write");
exit(3);
}
else
{
printf("Client:\n");
printf(" %s\n",send_buff);
}
read_flag=1;
write_flag=0;
memset(recv_buff,0x00,strlen(recv_buff));
}
else if(strlen(recv_buff)==0&&read_flag==1)
{
if(read(newsockfd,recv_buff,sizeof(recv_buff))<0)
{
perror("read");
exit(4);
}
else if(strlen(recv_buff)>0)
{
printf("Server:\n");
printf(" : %s\n",recv_buff);
memset(send_buff,0x00,strlen(send_buff));//接受到数据后清空发送缓冲区
write_flag=1;
read_flag=0;
}
}
}
close(sockfd);
return 0;
}
效果图:
版权声明:本文为a158337原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。