TCP客户端服务器编程模型:

服务器:

  1. 调用socket函数创建套接字
  2. 调用bind绑定本地IP和端口
  3. 调用listen启动监听(准备好接收客户端链接的队列)
  4. 调用accept从已连接队列中提取第一个连接。(如果没有,会阻塞。)
  5. 调用I/O函数(read/write)与客户端通讯
  6. 调用close关闭套接字。(多个套接字)

客户端:

  1. 调用socket创建套接字
  2. 调用connect连接服务器
  3. 调用I/O函数(read/write)与服务器通讯
  4. 调用close关闭套接字

Linux下和Mac下代码一样的,可能有头文件不太一样,用man命令进去查看即可。

功能:

  1. 客户端连到服务器,服务器打印连接的客户端IP和端口,返回给客户端当前服务器时间。
  2. 服务器加了一个信号捕获函数,ctrl+c停止服务器进程。
  3. 如果不写客户端,使用telnet 127.0.0.1 8888 依然可以收到服务器返回的时间字符串。

服务器代码 time_tcp_server.c:

#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h> #define SERVER_PORT 8888
#define LISTEN_QUEUE_SISE 10 int socketfd; void signal_handler(int signo)
{
printf("this serveice close\n");
close(socketfd);
exit();
} void out_clientinfo(const struct sockaddr_in* outsockaddr)
{
char ipstr[];
memset(ipstr, , sizeof(ipstr));
// 将地址从网络字节序转换为点分十进制
inet_ntop(AF_INET, &outsockaddr->sin_addr.s_addr, ipstr, sizeof(ipstr)); printf("Connected by %s(%d)\n", ipstr, ntohs(outsockaddr->sin_port));
} void dosomething(int fd)
{
//获取系统当前时间
long t = time();
char* times = ctime(&t);
size_t size = strlen(times)*sizeof(char);
//将时间写回到客户端
if(write(fd, times, size) != size)
{
perror("write to client error");
}
} int main(int argc, char const *argv[])
{
if (signal(SIGINT, signal_handler) == SIG_ERR)
{
perror("signal error");
exit();
} // 1 sokect
// AF_INET ipv4
// SOCK_STREAM tcp
if((socketfd = socket(AF_INET, SOCK_STREAM, )) < )
{
perror("socket error");
exit();
} // 2 bind 绑定本地地址和端口
struct sockaddr_in serveraddr;
memset(&serveraddr, , sizeof(serveraddr));
serveraddr.sin_family = AF_INET;//ipv4
serveraddr.sin_port = htons(SERVER_PORT); //端口
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);//响应任意网卡的请求
if(bind(socketfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < )
{
perror("bind error");
exit();
} // 3 listen 启动监听 通知系统接受来自客户端的连接 准备好连接队列
if(listen(socketfd, LISTEN_QUEUE_SISE) < )
{
perror("listen error");
exit();
}
struct sockaddr_in clientaddr;
socklen_t clientaddr_len = sizeof(clientaddr);
while()
{
// 4 accept 从队列拿出第一个
// clientaddr获取客户端的地址信息,是传出参数
int clientfd = accept(socketfd, (struct sockaddr*)&clientaddr, &clientaddr_len);
if (clientfd < )
{
perror("accept error");
continue;
}
// 5 read/write
out_clientinfo(&clientaddr);
dosomething(clientfd); // 6 close
close(clientfd);
} // 6 close
return ;
}

客户端代码time_tcp_client:

#include <sys/socket.h>
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h> #define SERVER_PORT 8888
#define SERVER_IP 127.0.0.1 int main(int argc, char const *argv[])
{
//1 创建socket int socketfd = socket(AF_INET, SOCK_STREAM, );
if (socketfd < )
{
perror("socket error");
exit();
} //2 connect
struct sockaddr_in serveraddr;
memset(&serveraddr, , sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(SERVER_PORT); if(connect(socketfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < )
{
perror("connect error");
exit();
} //3 read write
char buf[];
  //read是阻塞函数 如果服务器没有下发消息,会一直阻塞在这里,知道收到消息。
if (read(socketfd, buf, sizeof(buf)) > )
{
printf("%s",buf);
} //4 close
close(socketfd);
return ;
}

本例只是简单的处理,服务器返回客户端一个时间,然后关闭了socket。

如果要进行双向通信,服务器势必要调用read函数,而read默认阻塞,那么如果客户端不向服务器发送数据,则主线程一直阻塞,其它客户端无法连接成功。这就需要处理高并发问题。

服务器高并发处理的三种方式

  1. 多进程 https://www.cnblogs.com/lan0725/p/11634709.html
  2. 多线程 https://www.cnblogs.com/lan0725/p/11639142.html
  3.  I/O多路复用

macos下简单的socket服务器+客户端的更多相关文章

  1. Linux下简单的socket通信实例

    Linux下简单的socket通信实例 If you spend too much time thinking about a thing, you’ll never get it done. —Br ...

  2. windows下的C++ socket服务器(1)

    windows下的一个C++ socket服务器,用到了C++11的相关内容,现在还不是很完善,以后会不断改进的! #include <winsock2.h>//1 以后会用这种方式对特定 ...

  3. TCP/TP编程 - 一个简单的Linux下C写的socket服务器客户端程序

    服务端: hello_server.c #include <stdio.h> #include <stdlib.h> #include <string.h> #in ...

  4. 最简单的socket服务器与客户端

    服务器: //服务器 #include <stdio.h> #include <netinet/in.h> #include <unistd.h> #include ...

  5. python简单的socket 服务器和客户端

    服务器端代码 if "__main__" == __name__: try: sock = socket.socket(socket.AF_INET, socket.SOCK_ST ...

  6. windows下的C++ socket服务器(2)

    int main(int ac, char *av[]) { ); ) { exit(); } thread t; ) { int socket_fd = accept(tcp_socket, nul ...

  7. windows下的C++ socket服务器(3)

    int make_server_socket(int port) { WSADATA inet_WsaData; WSAStartup(MAKEWORD(), &inet_WsaData); ...

  8. windows下的C++ socket服务器(4)

    void handleAccept(int socket_fd) { ] = { '\0' }; string cmd; string filename; recv(socket_fd, buf, ) ...

  9. c++下基于windows socket的单线程服务器客户端程序(基于TCP协议)

    今天自己编写了一个简单的c++服务器客户端程序,注释较详细,在此做个笔记. windows下socket编程的主要流程可概括如下:初始化ws2_32.dll动态库-->创建套接字-->绑定 ...

随机推荐

  1. SpringCloud 与 Dubbo区别

    总览   Dubbo SpringCloud 服务注册中心 Zookeeper Spring Cloud Netfix Eureka 服务调用方式 RPC REST API 服务监控 Dubbo-mo ...

  2. [Paper Reading] Show, Attend and Tell: Neural Image Caption Generation with Visual Attention

    论文链接:https://arxiv.org/pdf/1502.03044.pdf 代码链接:https://github.com/kelvinxu/arctic-captions & htt ...

  3. 攻防世界MISC新手练习

    0x01 this_is_flag 对!!!这就是flag 0x02 ext3 题目提示是Linux光盘,附件下载下来 在linux中挂载mount linux /mnt 找一下flagtrings ...

  4. JavaScript 短路值

    了解表达式中的短路值. 逻辑运算从左到右.逻辑或运算,当左边的条件成立时,后面的条件将不再参与运算.因此在逻辑或运算中,尽量将条件结果为true的放第一位.而在逻辑与运算中,尽量将条件结果为false ...

  5. Java核心第五章继承

    5.1类 超类(父类.基类)  子类(派生类) 使用关键字extends来继承 对于子类想访问父类的私有域,则必须要借助公有接口,在父类中的公有方法正是这样的接口 为了防止子类定义了与父类一样的成员函 ...

  6. 《MIT 6.828 Lab 1 Exercise 7》实验报告

    本实验链接:mit 6.828 lab1 Exercise 7. 题目 Exercise 7. Use QEMU and GDB to trace into the JOS kernel and st ...

  7. String、StringBuilder、StringBuffer的爱恨情仇

    第三阶段 JAVA常见对象的学习 StringBuffer和StringBuilder类 (一) StringBuffer类的概述 (1) 基本概述 下文以StringBuffer为例 前面我们用字符 ...

  8. 异构平台mysql-oracle(ogg)安装部署

      如图所示:源端采用Mysql库,目标端采用Oracle库 一.OGG安装配置(源端) 1.OGG下载 https://edelivery.oracle.com/EPD/Download/get_f ...

  9. HttpServletResponse对象(转)

    Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象.request和response对象即然代表请求和响应,那我们要 ...

  10. MySQL 官方样板数据库sakila

    Sakila示例数据库最初由MySQL AB文档团队的前成员Mike Hillyer开发,旨在提供可用于书籍,教程,文章,样本等示例的标准模式. Sakila示例数据库还用于突出MySQL的最新功能, ...