思路:

点对点通信,其原理也比较简单,在前面回显服务器的基础上,我们分别在服务端和客户端都使用两个线程,一个线程负责发送数据包,一个线程负责接收数据包。

代码如下:

客户端:

/*************************************************************************
> File Name: p2pcli.c
> Author: ma6174
> Mail: ma6174@163.com
> Created Time: Sun 05 Oct 2014 09:26:40 PM HKT
************************************************************************/ #include<stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h> #include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h> #define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while() void handler(int sig)
{
printf("recv a sigal sig = %d\n", sig);
printf("parent exit\n");
exit();
} int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr; if(argc != )
{
//printf("usage: p2pcli <IPaddress> ");
//exit(0);
ERR_EXIT("usage: p2pcli <IPaddress> ");
} sockfd = socket(AF_INET, SOCK_STREAM, ); memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons();
servaddr.sin_addr.s_addr = inet_addr(argv[]); if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < )
{
ERR_EXIT("connect");
} pid_t pid;
pid = fork();
if(pid == -)
{
ERR_EXIT("fork");
}
else if(pid == )
{
//child
char recvbuf[] = {};
while()
{
memset(recvbuf, , sizeof(recvbuf));
int ret = read(sockfd, recvbuf, sizeof(recvbuf));
if(ret == -)
{
ERR_EXIT("read");
break;
}
else if(ret == )
{
printf("peer client close.\n");
break;
}
else
{
fputs(recvbuf, stdout);
}
}
printf("child thread exit\n");
kill(getppid(), SIGUSR1);
exit(EXIT_SUCCESS); }
else
{
signal(SIGUSR1, handler);
char sendbuf[] = {};
while(fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)
{
//send to server.
write(sockfd, sendbuf, strlen(sendbuf));
memset(sendbuf, , sizeof(sendbuf));
}
exit(EXIT_SUCCESS);
}
//communication
return ;
}

服务端:

/*************************************************************************
> File Name: p2psrv.c
> Author: ma6174
> Mail: ma6174@163.com
> Created Time: Sun 05 Oct 2014 08:27:06 PM HKT
************************************************************************/ #include<stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h> #include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h> #define ERR_EXIT(m)\
do\
{\
perror(m);\
exit(EXIT_FAILURE);\
}while()
/**
*child thread signal exit function
**/
void handler(int sig)
{
printf("recv a signal sig=%d\n", sig);
printf("child exit\n");
exit(EXIT_SUCCESS);
} int main()
{
int listenfd;
if( (listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < )
{
ERR_EXIT("socket");
} struct sockaddr_in servaddr;
memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons();
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //reuse address
int on = ;
if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
{
ERR_EXIT("setsockopt");
} if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < )
{
ERR_EXIT("bind");
} if(listen(listenfd, SOMAXCONN) < )
{
ERR_EXIT("listen");
} struct sockaddr_in peeraddr;
socklen_t peerlen = sizeof(peeraddr);
int connfd; if( (connfd = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen)) < )
{
ERR_EXIT("accept");
} printf("ip=%s, port=%d\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port)); pid_t pid;
pid = fork();
if(pid == -)
{
ERR_EXIT("fork");
}
else if(pid == )
{
//child
signal(SIGUSR1, handler);
char sendbuf[];
memset(sendbuf, , sizeof(sendbuf));
while(fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)
{
write(connfd, sendbuf, strlen(sendbuf));
memset(sendbuf, , sizeof(sendbuf));
}
exit(EXIT_SUCCESS);
}
else
{
char recvbuf[];
while()
{
memset(recvbuf, , sizeof(recvbuf));
int ret = read(connfd, recvbuf, sizeof(recvbuf));
if(ret == -)
{
ERR_EXIT("read");
}
else if(ret == )
{
printf("peer client close.\n");
break;
}
else
{
fputs(recvbuf, stdout);
}
}
printf("parent exit\n");
kill(pid, SIGUSR1);
exit(EXIT_SUCCESS);
} close(connfd);
close(listenfd);
return ;
}

《UNIX网络编程》之点对点通信的更多相关文章

  1. UNIX网络编程——getsockname和getpeername函数

    UNIX网络编程--getsockname和getpeername函数   来源:网络转载   http://www.educity.cn/linux/1241293.html     这两个函数或者 ...

  2. 【LINUX/UNIX网络编程】之简单多线程服务器(多人群聊系统)

    RT,Linux下使用c实现的多线程服务器.这个真是简单的不能再简单的了,有写的不好的地方,还希望大神轻拍.(>﹏<) 本学期Linux.unix网络编程的第四个作业. 先上实验要求: [ ...

  3. 【LINUX/UNIX网络编程】之使用消息队列,信号量和命名管道实现的多进程服务器(多人群聊系统)

    RT,使用消息队列,信号量和命名管道实现的多人群聊系统. 本学期Linux.unix网络编程的第三个作业. 先上实验要求: 实验三  多进程服务器 [实验目的] 1.熟练掌握进程的创建与终止方法: 2 ...

  4. 【Linux/unix网络编程】之使用socket进行TCP编程

    实验一 TCP数据发送与接收 [实验目的] 1.熟练掌握套接字函数的使用方法. 2.应用套接字函数完成基本TCP通讯,实现服务器与客户端的信息交互. [实验学时] 4学时 [实验内容] 实现一个服务器 ...

  5. Unix网络编程--卷二:进程间通信

    Unix网络编程--卷二:进程间通信 本书是一部Unix网络编程的经典之作!进程间通信(IPC)几乎是所有Unix程序性能的关键,理解IPC也是理解如何开发不同主机网络应用程序的必要条件.本书从对Po ...

  6. Unix网络编程--卷一:套接字联网API

    UNIX网络编程--卷一:套接字联网API 本书面对的读者是那些希望自己编写的程序能够使用成为套接字(socket)的API进行彼此通信的人. 目录: 0.准备环境 1.简介 2.传输层:TCP.UD ...

  7. [转载] 读《UNIX网络编程 卷1:套接字联网API》

    原文: http://cstdlib.com/tech/2014/10/09/read-unix-network-programming-1/ 文章写的很清楚, 适合初学者 最近看了<UNIX网 ...

  8. UNIX网络编程

    UNIX网络编程--socket的keep http://www.68idc.cn/help/opersys/unixbsd/20150731471448.html

  9. UNIX网络编程——网络IPC:套接字

    UNIX网络编程——网络IPC:套接字 Contents 套接字接口 套接字描述符 寻址 字节序 地址格式 地址查询 绑定地址 建立连接 数据传输 套接字选项 带外数据 UNIX域套接字 使用套接字的 ...

  10. 《 UNIX网络编程》源码的使用

    学习编程这东西,看代码,改代码,运行代码这样才能学到实际东西!本书说在www.unpbook.com可以获取源码,不过打不开!所以google unpv13e.tar.gz 并在网络上找到了:源码:h ...

随机推荐

  1. UITouch触摸事件

    UITouch触摸事件 主要为三个方法 1.-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{2.3. UITouch * ...

  2. Ubuntu12.4 64位 安装 arm linux gcc 4.3.2

    一.下载arm linux gcc 4.3.2 http://pan.baidu.com/share/link?shareid=1575352696&uk=2754759285&fid ...

  3. [技术翻译]Guava-libraries(一): 用户指导

    用户指导 本文翻译自http://code.google.com/p/guava-libraries/wiki/GuavaExplained,由十八子将翻译,发表于博客园 http://www.cnb ...

  4. Android Studio删除Project

    最直截了当的方法是在Project所在目录直接删除整个Project,然后再次打开Android Studio的欢迎界面中把光标移到你的Project上,然后按键盘上的Delete键即可! 参考自st ...

  5. ONVIF Event消息解析(How to work with gSoap)

    Prepare Requirements ONVIF Event gSoap reference ONVIF Specification 问题描述 Event是ONVIF核心规范中一块, 文档解释了如 ...

  6. 分片传输——send和recv函数

    最近在写socket编程收发数据,对于如何发送和接收大量数据,一直在思考.send和recv一般缓存区大小为4K,但是如果你要传输的数据超过了这个标准该如何做呢. 我想到的就是如改写write和rea ...

  7. jquery图片轮播代码

    自己写的轮播代码 来张样式效果图 先贴HTML样式 <body> <div id = "wrap"> <div id="lunbo-img& ...

  8. underscorejs-sortBy学习

    2.17 sortBy 2.17.1 语法 _.sortBy(list, iteratee, [context]) 2.17.2 说明 返回一个排序后的list拷贝副本. list为集合,如数组.对象 ...

  9. 转:Hprose for php(二)——服务器

    文章来自于:http://blog.csdn.net/half1/article/details/21252879 本文将介绍Hprose for php服务器的更多细节 1.发布服务 Hprose提 ...

  10. 用UNetbootin来安装USB LINUX,好像比ULTRA ISO省事

    UNetbootin can create a bootable Live USB drive, or it can make a "frugal install" on your ...