2025年3月30日 星期日 甲辰(龙)年 月廿九 夜 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 网络通信

基础套接字-简单聊天程序实现

时间:08-01来源:作者:点击数:24

聊天程序实现

  • 用多进程方式实现点对点聊天
    • 一个进程用来获得输入,一个进程用来获得对方发来的消息
客户端
  • //p2pcli.c
  • #include <stdio.h>
  • #include <string.h>
  • #include <stdlib.h>
  • #include <sys/socket.h>
  • #include <arpa/inet.h>
  • #include <netinet/in.h>
  • #include <sys/types.h>
  • #include <unistd.h>
  • #include <errno.h>
  • #include <signal.h>
  • void handler(int sig)
  • {
  • exit(EXIT_SUCCESS);
  • }
  • int main()
  • {
  • int sock;
  • //创建一个套接字
  • if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0){
  • perror("Creat socket failed.");
  • exit(1);
  • }
  • /*int socket(int domain, int type, int protocol);*/
  • struct sockaddr_in servaddr;
  • memset(&servaddr, 0, sizeof(servaddr));
  • servaddr.sin_family = AF_INET;
  • servaddr.sin_port = htons(9000);
  • servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  • /*servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");*/
  • /*inet_aton("127.0.0.1", &servaddr.sin_addr);*/
  • if(connect(sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
  • perror("connect() error");
  • exit(1);
  • }
  • //
  • pid_t pid;
  • pid = fork();
  • if(pid == -1){
  • perror("fork() error");
  • }
  • if(pid == 0){
  • //子进程接收对方发送的数据
  • char recvbuf[1024] = {0};
  • while(1){
  • memset(recvbuf, 0, sizeof(recvbuf));
  • int ret = read(sock, recvbuf, sizeof(recvbuf));
  • if(ret == -1){
  • perror("read() error");
  • exit(1);
  • } else if(ret == 0){
  • printf("peer close\n");
  • break;
  • }
  • fputs(recvbuf, stdout);
  • }
  • close(sock);
  • kill(getppid(), SIGUSR1);//通知父进程退出
  • exit(EXIT_SUCCESS);
  • } else {
  • //主进程发送数据
  • signal(SIGUSR1, handler);
  • char sendbuf[1024] = {0};
  • while(fgets(sendbuf, sizeof(sendbuf), stdin) != NULL){
  • write(sock, sendbuf, strlen(sendbuf));
  • memset(sendbuf, 0, sizeof(sendbuf));
  • }
  • close(sock);
  • exit(EXIT_SUCCESS);
  • }
  • return 0;
  • }
服务器端
  • //p2pserv.c
  • #include <stdio.h>
  • #include <string.h>
  • #include <stdlib.h>
  • #include <sys/socket.h>
  • #include <arpa/inet.h>
  • #include <netinet/in.h>
  • #include <sys/types.h>
  • #include <unistd.h>
  • #include <errno.h>
  • #include <signal.h>
  • void handler(int sig)
  • {
  • exit(EXIT_SUCCESS);
  • }
  • int main()
  • {
  • int listenfd;
  • //创建一个套接字
  • if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
  • perror("Create socket failed.");
  • exit(1);
  • }
  • /*int socket(int domain, int type, int protocol);*/
  • struct sockaddr_in servaddr;
  • memset(&servaddr, 0, sizeof(servaddr));
  • servaddr.sin_family = AF_INET;
  • servaddr.sin_port = htons(9000);
  • servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  • /*servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");*/
  • /*inet_aton("127.0.0.1", &servaddr.sin_addr);*/
  • int on = 1;//选项开启标志
  • //设置地址重复利用
  • if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0){
  • perror("setsockopt error.");
  • exit(1);
  • }
  • if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
  • perror("bind error.");
  • exit(1);
  • }
  • //绑定
  • if(listen(listenfd, SOMAXCONN) < 0){
  • perror("listen() error.");
  • exit(1);
  • }
  • //监听
  • struct sockaddr_in peeraddr;
  • socklen_t peerlen = sizeof(peeraddr);
  • int conn;
  • if((conn = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen)) < 0){
  • perror("accept() error");
  • exit(1);
  • }
  • printf("ip = %s, port = %d\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port));
  • //
  • pid_t pid;
  • pid = fork();
  • if(pid == -1){
  • perror("fork() error");
  • exit(1);
  • }
  • if(pid == 0){
  • //发送数据的子进程
  • signal(SIGUSR1, handler);
  • char sendbuf[1024] = {0};
  • while(fgets(sendbuf, sizeof(sendbuf), stdin) != NULL){
  • write(conn, sendbuf, strlen(sendbuf));
  • memset(sendbuf, 0, sizeof(sendbuf));
  • }
  • exit(EXIT_SUCCESS);
  • } else {
  • //父进程用于获取对方发送的数据
  • char recvbuf[1024];
  • while (1){
  • memset(recvbuf, 0, sizeof(recvbuf));
  • int ret = read(conn, recvbuf, sizeof(recvbuf));
  • if(ret == -1){
  • perror("read error");
  • exit(1);
  • } else if(ret == 0){
  • printf("peer close\n");
  • break;
  • }
  • fputs (recvbuf, stdout);
  • }
  • kill(pid, SIGUSR1);//通知子进程退出
  • exit(EXIT_SUCCESS);
  • }
  • return 0;
  • }
实验结果
这里写图片描述
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐