C语言能干什么?手把手教你写一个简单的聊天软件

您所在的位置:网站首页 gravity聊天软件怎么注册 C语言能干什么?手把手教你写一个简单的聊天软件

C语言能干什么?手把手教你写一个简单的聊天软件

2024-07-09 18:25| 来源: 网络整理| 查看: 265

一、服务端代码

因为端口号容易被占用的原因,所以IP地址和端口号采用参数传递的方法,即

int main(int argc,char **argv)

1、头文件

#include #include #include #include #include #include #include #include

这些头文件全都是所调用函数需要的,比如read(),socket()等等,没有就会报错。

2、创建套接字(Socket)

int s_fd; s_fd = socket(AF_INET,SOCK_STREAM,0);//创建套接字 if(s_fd == -1){ perror("socket"); //打印错误信息 exit(-1); }

s_fd 表示套接字描述符,AF_INET表示IPv4因特网协议,SOCK_STREAM表示使用TCP协议,0表示选择对应默认协议。

3、绑定IP地址和端口号到Socket

struct sockaddr_in s_addr; s_addr.sin_family = AF_INET;//IPv4协议 s_addr.sin_port = htons(atoi(argv[2]));//配置端口号, //htons函数为网络字节序和主机字节序的转化 inet_aton(argv[1],&s_addr.sin_addr);//将IP地址配置到s_addr.sin_addr bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));//绑定

inet_aton: 把字符串形式的IP地址转为网络能识别的格式 htons: 网络字节序和主机字节序的转化

也就是说sockaddr_in里面有三个成员,有地址协议,监听端口号和IP地址,端口号是随便设置的,只要在端口号范围内就可以,

bind函数是绑定套接字和sockaddr_in结构体,这里应该要注意,bind函数里面第二个参数它需要的是sockaddr 但是我们用的sockaddr _in,所以要强制转化为sockaddr 类型,不然会报错,即(struct sockaddr *)&s_addr。

4、监听

绑定好IP地址和端口号后,服务器就需要监听来自客户端的请求

listen(s_fd,5);

s_fd 表示套接字返回的套接字描述符,5表示最大监听 5个。

5、连接

当服务器监听到客户端的请求时,就需要连接了,即

int c_fd; struct sockaddr_in c_addr; //用来返回已经连接的客户端的协议地址 int clen = sizeof(struct sockaddr_in); //结构体长度 c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen); //连接客户端 if(c_fd == -1){ perror("accept"); //打印错误信息 }

accept函数里面第二个参数它需要的是sockaddr ,但是我们用的sockaddr _in,所以要强制转化为sockaddr 类型,c_fd 是一个新的套接字描述符,连接成功后对数据的操作,使用的都是这个新的套接字描述符。

6、交换数据

char readBuf[1024]; char msg[1024]; int n_read; memset(msg,0,sizeof(msg)); //将msg清空 memset(readBuf,0,sizeof(readBuf));//将readBuf清空 printf("input: "); //提示输入数据 gets(msg); //数据放入到msg中 write(c_fd,msg,strlen(msg)); //将输入的数据写入到套接字描述符c_fd中的客户端 n_read = read(c_fd,readBuf,1024);//将套接字描述符c_fd中的数据读1024个到readBuf中 if(n_read == -1){ perror("read"); //打印错误信息 }else{ printf("get message:%s\n",readBuf); //将从客户端读到的数据打印 }

上面代码只能交换一次数据,不能循环的发送数据,所以需要死循环。在网络进程中,父进程一直等待客户端的服务请求,当收到客户端的请求时,父进程调用fork函数创建子进程,使子进程来处理,父进程则继续等待下一个客户端请求到达。

while(1){ //一直进行连接客户端 c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen); if(c_fd == -1){ perror("accept"); } printf("get connect: %s\n",inet_ntoa(c_addr.sin_addr));//打印客户端的IP地址 if(fork() == 0){ //连接到一个客户端后创建一个子进程来进行数据的交换 if(fork() == 0){ //再创建一个子进程来进行数据的写入 while(1){ //可以一直写入数据 memset(msg,0,sizeof(msg)); printf("input: "); gets(msg); write(c_fd,msg,strlen(msg)); } } while(1){ //可以一直读取数据 memset(readBuf,0,sizeof(readBuf)); n_read = read(c_fd,readBuf,128); if(n_read == -1){ perror("read"); }else{ printf("get message:%s\n",readBuf); } } } } 二、客户端代码

客户端IP地址和端口号也采用参数传递的方法,即

int main(int argc,char **argv)

1、头文件

#include #include #include #include #include #include #include #include

全部都是所用函数头文件,没有则报错

2、创建套接字(Socket)

int c_fd; c_fd = socket(AF_INET,SOCK_STREAM,0);//创建套接字 if(c_fd == -1){ perror("socket"); //打印错误信息 exit(-1); }

c_fd 表示套接字描述符,AF_INET表示IPv4因特网协议,SOCK_STREAM表示使用TCP协议,0表示选择对应默认协议。

3、绑定IP地址和端口号到Socket

struct sockaddr_in c_addr; c_addr.sin_family = AF_INET;//IPv4协议 c_addr.sin_port = htons(atoi(argv[2]));//配置端口号, //htons函数为网络字节序和主机字节序的转化 inet_aton(argv[1],&c_addr.sin_addr);//将IP地址配置到c_addr.sin_addr bind(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in));//绑定

和服务端一样,bind函数是绑定套接字和sockaddr_in结构体,bind函数里面第二个参数它需要的是sockaddr ,但是我们用的sockaddr _in,所以要强制转化为sockaddr 类型。

4、客户端的连接(connect函数)

int cont; cont = connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr)); if(cont == -1){ perror("connect"); //打印错误信息 exit(-1); //退出进程 }

connect函数用于绑定之后客户端,与服务器建立连接参数。

5、交换数据

char readBuf[1024]; char msg[1024]; int n_read; while(1){ if(fork() == 0){ //创建子进程来进行数据的交换 while(1){ //一直向服务器写入数据 printf("input : "); //提示输入 memset(msg,0,sizeof(msg)); //清空 gets(msg); //获取字符 write(c_fd,msg,strlen(msg)); //将输入的内容写入到c_fd中 } } while(1){ memset(readBuf,0,sizeof(readBuf)); //将readBuf清空 n_read = read(c_fd,readBuf,128); //将c_fd的内容读到readBuf中 if(n_read == -1){ perror("read"); //打印错误信息 }else{ printf("get message:%s\n",readBuf); //将从服务器读到的数据打印 } } }

这样一个简单的聊天软件就写好了,虽然没有页面,但是实现了服务器和客户端通过网络进行通信的功能,

三、运行结果



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3