http://blog.sina.com.cn/s/blog_87766e4a0100yp7a.html

1、 基于多线程实现一个服务器和一个客户端实现全双工通信

服务器端创建两个线程:一个用于接收客户端发送过来的信息;一个用来给客户端发送信息。

客户端也创建两个线程:一个用于接收服务器端发送过来的信息;一个用来给服务器端发送信息。

 

2、 示例代码

服务器端的代码client.c

#include <sys/types.h>

#include <sys/socket.h>

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <unistd.h>

#include <netinet/in.h>

#define SERVPORT 3333

#define BACKLOG 10                 //请求队列中的最大请求数

#define MAX_CONNECTED_NO 10  //最大是128台电脑连接

#define MAXDATASIZE 100

void pthread_recv(void *arg);

void Pthread_send(void * arg);

int main()

{

struct sockaddr_in server_sockaddr,client_sockaddr;

int sockfd,client_fd,sin_size,ret;

pthread_t id1,id2;

sin_size =sizeof(struct sockaddr);

//struct sockaddr_in server_sockaddr,client_sockaddr;

//建立一个socket连接

//目前都是AF_INET(ipv4);SOCK_STREAM(TCP),如果是UDP,则SOCK_DGRAM

if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1){

perror("socket");

exit(1);

}

printf("socket success!,sockfd=%d\n",sockfd);

//bind用于本地IP地址和端口的绑定

server_sockaddr.sin_family=AF_INET;

server_sockaddr.sin_port=htons(SERVPORT);

server_sockaddr.sin_addr.s_addr=INADDR_ANY;         //htonl(INADDR_ANY)

bzero(&(server_sockaddr.sin_zero),8);

//把本端的信息绑定

if(bind(sockfd,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr))==-1)

{

perror("bind");

exit(1);

}

printf("bind success!\n");

if(listen(sockfd,BACKLOG)==-1)

{

perror("listen");

exit(1);

}

printf("listening....\n");

//接受并保存客户端的信息

if((client_fd=accept(sockfd,(struct sockaddr *)&client_sockaddr,&sin_size))==-1)

{

perror("accept");

exit(1);

}

printf("client_fd=%d",client_fd);

pthread_create(&id1,NULL,(void *) pthread_recv,(void*)&client_fd);

if(ret != 0)

perror("pthread_recv creat");

ret=pthread_create(&id2,NULL,(void *)Pthread_send,(void*)&client_fd);

if(ret != 0)

perror("Pthread_send creat");

pthread_join(id1,NULL);

pthread_join(id2,NULL);

close(sockfd);

}

//服务器发送线程

void Pthread_send(void * arg)

{

int buf_len, client_fd,sendbytes;

char buf[MAXDATASIZE];

client_fd = *((int *)arg);

printf("server send: ");

while(1)

{

fgets(buf,MAXDATASIZE,stdin);

buf_len =sizeof(buf);

if((sendbytes = send(client_fd ,buf,buf_len,0))==-1)

{

perror("send");

exit(1);

}

if(!strncmp(buf,"end",3))         //只比较字符串的前三个字符

break;

sleep(2);

}

}

//服务器接收数据线程

void pthread_recv(void *arg)

{

int buf_len, client_fd,recvbytes;

char buf[MAXDATASIZE];

client_fd = *((int *)arg);

//接收服务端发来的信息

while(1)

{

if((recvbytes = recv(client_fd ,buf,MAXDATASIZE,0))==-1)

{

perror("recv");

exit(1);

}

else

{

buf[recvbytes]=0;

printf("server received data from server is :%s\n",buf);

if(!strncmp(buf,"end",3))         //只比较字符串前三个字符

break;

}

sleep(1);

}

}

客户端的代码:

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <netdb.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#define SERVPORT 3333

#define MAXDATASIZE 100

void pthread_recv(void *arg);

void Pthread_send(void * arg);

main(int argc,char *argv[]){

int sockfd,sin_size,ret;

struct hostent *host;

pthread_t id1,id2;

struct sockaddr_in serv_addr;         //套接字的地址结构

struct sockaddr_in server_sockaddr;

if(argc < 2)

{

fprintf(stderr,"Please enter the server's hostname!\n");

exit(1);

}

//AF_INET:使用的是IPV4

//SOCK_STREAM:流式套接字

if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)

{

perror("socket");

exit(1);

}

printf("sockfd=%d\n",sockfd);

serv_addr.sin_family=AF_INET;

serv_addr.sin_port=htons(SERVPORT);

//serv_addr.sin_addr=*((struct in_addr *)host->h_addr);

//host->h_addr强制类型转换;建议直接使用下面的方法

serv_addr.sin_addr.s_addr=inet_addr(argv[1]);   //"127.0.0.1");       Internet地址

bzero(&(serv_addr.sin_zero),8);

//连接

if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1)

{

perror("connect");

exit(1);

}

ret=pthread_create(&id1,NULL,(void *)Pthread_send,(void*)&sockfd);

if(ret != 0)

perror("Pthread_send creat");

pthread_create(&id2,NULL,(void *) pthread_recv,(void*)&sockfd);

if(ret != 0)

perror("pthread_recv creat");

pthread_join(id1,NULL);

pthread_join(id2,NULL);

close(sockfd);

}

//客户端发送数据线程

void Pthread_send(void * arg)

{

int buf_len, sockfd,sendbytes;

char buf[MAXDATASIZE];

sockfd = *((int *)arg);

printf("client send: ");

while(1)

{

fgets(buf,MAXDATASIZE,stdin);

buf_len =sizeof(buf);

if((sendbytes = send(sockfd,buf,buf_len,0))==-1)

{

perror("send");

exit(1);

}

if(!strncmp(buf,"end",3))         //只比较字符串的前三个字符

break;

sleep(2);

}

}

//客户端接收数据线程

void pthread_recv(void *arg)

{

int buf_len, sockfd,recvbytes;

char buf[MAXDATASIZE];

sockfd = *((int *)arg);

//接收服务端发来的信息

while(1)

{

if((recvbytes = recv(sockfd,buf,MAXDATASIZE,0))==-1)

{

perror("recv");

exit(1);

}

else

{

buf[recvbytes]=0;

printf("client received data from server is :%s\n",buf);

if(!strncmp(buf,"end",3))         //只比较字符串的前三个字符

break;

}

sleep(1);

}

}

客户端和服务器实现全双工通信(基于线程)相关推荐

  1. udp 全双工通信 linux,客户端和服务器实现全双工通信(基于线程)

    客户端和服务器实现全双工通信(基于线程) 1. 基于多线程实现一个服务器和一个客户端实现全双工通信 服务器端创建两个线程:一个用于接收客户端发送过来的信息:一个用来给客户端发送信息. 客户端也创建两个 ...

  2. 客户端和服务器之间的信息结构,客户端与服务器之间的通信过程

    客户端与服务器之间的通信过程 内容精选 换一换 一.HTTP概念超文本传输协议(HTTP,HyperTextTransferProtocol)是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必 ...

  3. 客户端与服务器之间的通信过程

    客户端与服务器之间的通信过程主要分为三步:请求--处理--响应 1.客户端发起请求 2.服务器处理本次请求 3.服务器响应客户端

  4. java iso8583 socket 服务_JAVA客户端amp;服务器的socket通信

    JAVA客户端&服务器的socket通信 socket是两台主机之间的一个连接通道,它可以完成七个基本操作: 发送远程机器 发送数据 接收数据 关闭连接 绑定端口 监听入站数据 再绑定端口上接 ...

  5. java socket 全双工客户端_java socket实现全双工通信

    单工.半双工和全双工的定义 如果在通信过程的任意时刻,信息只能由一方A传到另一方B,则称为单工. 如果在任意时刻,信息既可由A传到B,又能由B传A,但只能由一个方向上的传输存在,称为半双工传输. 如果 ...

  6. VB6 通过winsock控件数组实现客户端和服务器多对一通信

    说明:我是在最近开发一个考试系统过程中搜索到上面文章的,它提供的思想非常实用.当然,这篇文章仅提供了一个基本思路,详细的实现在人民邮电出版社出版的<Visual Basic网络通信协议分析与应用 ...

  7. 想破解游戏协议?你知道客户端和服务器是怎么通信的?我来告诉你怎么定义的

    目录 1.Java项目引用 2.protobuf 的文件定义格式 基础类型 特殊字段 3.生成java类 4.使用协议 5.如何在游戏项目中使用 游戏服务器和客户端的通信有很多种形式,有的用http, ...

  8. Android客户端与服务器之间的通信

    本文将介绍Android客户端与服务器端的通信的简单实现方法. 要两点需要注意的地方: 1.Android 端记得在AndroidManifest.xml里记得获取一下网络权限,否则无法进行网络通信, ...

  9. android客户端与服务器交互数据(基于SAOP协议的远程调用标准,通过webservice可以将不同操作系统平台,不同语言,不同技术整合)

    在PC机器java客户端中,需要一些库,比如XFire,Axis2,CXF等等来支持访问WebService,但是这些库并不适合我们资源有限的android手机客户端,做过JAVA ME的人都知道有K ...

最新文章

  1. 案例:用户登录界面最全详解(JavaWeb)
  2. php图片旋转验证码,如何用php生成扭曲及旋转的验证码图片
  3. show Locks LockManager not specified解决
  4. php自动抓取文章图片,从文章中提取图片,把图片保存到本地,自动提取缩略图...
  5. java程序内存泄漏场景及预防
  6. 学习GRPC(一) 简单实现
  7. 将java编译成so库_利用android studio 生成 JNI需要的动态库so文件
  8. NYOJ 49 开心的小明(01背包)
  9. Windows下安装Tp6.0框架,图文。Thinkphp6.0安装教程
  10. 腾讯微博开放平台发布者分享会(陈思齐)
  11. 2013-2015阿里双十一技术网络文章总结
  12. 苹果ID申请开发者 双重认证问题?
  13. azul zing_Azul Systems CTO讨论Lambda并提高Java社区的投入
  14. Shifting Stacks【题解】
  15. 快速搭建centos7虚拟机——使用virtualbox+vagrant
  16. [iPad]手势及分页
  17. 中国ACM橡胶市场调研与投资预测报告(2022版)
  18. stm32的内存分布
  19. Oracle Distilled网站下的TimesTen相关帖子
  20. 剑侠情缘修改服务器列表名字,史上奇葩的游戏氪金活动,充钱就能改服务器名,剑侠情缘也在其中...

热门文章

  1. python爬虫新浪新闻_学习了《python网络爬虫实战》第一个爬虫,爬取新浪新闻
  2. mysql 不用缓存_mysql有自己的缓存机制,为什么还要用redis和memcac? 爱问知识人
  3. c语言对c99标准声明,C语言中C89与C99的区别
  4. dy96 .pw cc 05.php,05.php · 熟悉的陌生/php - Gitee.com
  5. 软件开发架构的演变过程
  6. 大数据学习笔记59:初探Kafka消息系统
  7. 安卓学习笔记42:基于HTTP网络编程
  8. Python编程基础08:循环结构
  9. Python案例:格式化输出斐波拉契数列
  10. 【BZOJ2744】【codevs2366】朋友圈,二分图最大匹配