下面是socket编程的服务器端

先看一个图,1

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h> //针对系统调用的封装 fork,pipe 各种i/o原语 read write 等 #include<sys/socket.h>
#include<netinet/in.h> //互联网地址族 定义数据结构sockaddr_in
#include<arpa/inet.h> //提供IP地址转换函数 #include<ctype.h> //一批C语言字符分类函数 用 于 测试字符是否属于特定的字符类别 topper()在这里 #define MAXLINE 80
#define SER_PORT 8000 int main(void){ struct sockaddr_in servaddr,cliaddr;
socklen_t cliaddr_len; int listenfd,connfd;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
int i,n;
char tt[] = "exit1"; //这里有字符数组和字符指针的区别的坑 具体百度查询
char *bb; listenfd = socket(AF_INET,SOCK_STREAM,); //
// domain 协议域 AF_INET AF_INET6,AF_LOCAL(AF_UNIX) AF_ROUTE
// type socket类型 SOCK_STREAM(流式socket 针对tcp ) SOCK_DGRAM(数据包 针对udp) SOCK_RAW
// protocol 协议 tcp协议,udp协议 stcp协议 tipc协议 bzero(&servaddr,sizeof(servaddr)); //初始化赋值为0 servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //任何ip //这里是大小端的 转换问题。。可以 百度
servaddr.sin_port = htons(SER_PORT); //端口 bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); //绑定链接的套接字描述符 和 地址和端口 listen(listenfd,); printf("Accepting connections ... \n ");
while(){ cliaddr_len = sizeof(cliaddr);
connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&cliaddr_len); //连接的套接字描述符 返回链接的地址 返回地址的缓冲区长度 //返回 客户端的套接字描述符
printf("connfd:%d------\n",connfd); printf("received from %s at PORT %d \n",
inet_ntop(AF_INET,&cliaddr.sin_addr,str,sizeof(str)),
ntohs(cliaddr.sin_port));
while(){
n = read(connfd,buf,MAXLINE); // read(int fd,void *buf, size_t count); 成功返回 读取的字节数 数据保存在buf上 读取客户端的数据 printf("%d,")
//printf("buf:%s-----%d\n",buf,strcmp(buf,"exit1"));
//printf("tt:%s-----%d\n",tt,strcmp(tt,"exit1"));
for(int i=;i<;i++){
tt[i] = buf[i];
}
printf("tt:%s-----%d\n",tt,strcmp(tt,"exit1"));
if(strcmp(tt,"exit1") == ){ //strcmp 对比的就是字符
close(connfd);
printf("close:-----\n");
break;
} for(i=; i < n; i++){
buf[i] = toupper(buf[i]);
}
write(connfd,buf,n); // // 向客户端写入数据
} } return ; } //这个程序有漏洞,如果客户端断线或者关闭,服务器就会死循环。 客户端的标准输入是阻塞的。。。其他都不是阻塞的。

客户端

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h> #include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h> #include<errno.h> //错误 #define MAXLINE 80
#define SER_PORT 8000 int main(int argc,char *argv[]){ struct sockaddr_in servaddr;
char buf[MAXLINE]; int sockfd,n;
char *str;
char tt[]; //if(argc != 2){
// fputs("usage: ./client message \n ",stderr);
// exit(1);
//} //str = argv[1]; sockfd = socket(AF_INET,SOCK_STREAM,); bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr);
servaddr.sin_port = htons(SER_PORT); if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr))<){
printf("connet error:%s\n",strerror(errno));
} //链接服务器 while(){ memset(buf,,MAXLINE);
printf("client connet server ...\n");
n = read(STDIN_FILENO,buf,MAXLINE); //从标准输入 读取数据
for(int i=;i<;i++){
tt[i] = buf[i];
}
if(strcmp(tt,"exit1") == ){
printf("exit server connect \n");
close(sockfd);
return ;
} write(sockfd,buf,n); //把我们的输入,写到服务器 if(strcmp(tt,"exit1") == ){
printf("exit server connect \n");
close(sockfd);
return ;
} n = read(sockfd,buf,MAXLINE); //从服务器读取数据 printf("Response from server:\n");
write(STDOUT_FILENO,buf,n); //写到标注输出上
printf("\n");
} close(sockfd);
return ; }

实验结果:

总结:一个socket建立一个连接,必须配合一个connect,对应的服务器端对应一个accept 。不能多次connet,多次是之后会报错,也不能同一个客户端socket多次accept,因为服务器已经有了,accept会阻塞等待其他客户端的socket。

最新文章

  1. 解决Java程序连接mysql数据库出现CommunicationsException: Communications link failure错误的问题
  2. 最小生成树のprim算法
  3. 分析-eclipse已经导入jar包了,但还是出现classNotFound异常
  4. 2014——&gt;2015,我的薪资依然是4.5
  5. 招聘信息:无线产品研发总监 60-100W
  6. -tableView: cellForRowAtIndexPath:方法不执行问题
  7. Sqlserver 关于游标
  8. Swift 学习笔记1
  9. c#反射机制判断同一个类的两个实例的值是否完全一样
  10. Codevs 4768 跳石头 NOIP2015 DAY2 T1
  11. Java Socket 简单梳理
  12. GDI+简单现实文字旋转
  13. XCL-Charts绘画面积图(AreaChart) 案件1
  14. gcc与g++的区别与联系
  15. 菜鸟的it之路-起航
  16. 分析Json/Xml的解析过程
  17. SSM-网站后台管理系统制作(1)
  18. Subsequence Count 2017ccpc网络赛 1006 dp+线段树维护矩阵
  19. NFS Server宕机后,NFS Client主机上df命令挂死
  20. Android 编程下实现 Activity 的透明效果

热门文章

  1. JAVA中获取当前运行的类名,方法名,行数
  2. JAVA中StringBuffer类常用方法
  3. 离职了,在家温故而知新----1 设计模式 &amp; 开头
  4. MongoDB基础之五:游标
  5. 很傻很二很简单的一个问题,json键值为变量如何取值
  6. context:annotation-config, mvc:annotation-driven, context:compont-scan 区别
  7. .NET十五周年生日快乐 (3月7日发布Visual Studio 2017正式版?)
  8. Java设计和实现方法
  9. Unity中的万能对象池
  10. Android项目实战(三十一):异步下载apk文件并安装(非静默安装)