Linux TCP客户端、服务器编程模型及实例

2023-11-03

Linux TCP客户端、服务器编程模型及实例


服务器模型:
1、绑定IPv4的地址(INADDR_ANY)和端口号(8888)
int listenfd, sockfd, opt = 1;
struct sockaddr_in server, client;
新建socket
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(listenfd < 0){
perror("Create socket fail.");
return -1;
}
设置地址可重用功能,防止异常退出无法短时间打开server
if((ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) < 0)
{
    perror("Error, set socket reuse addr failed");
  return -1;
}
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port   = htons(8888);
server.sin_addr.s_addr  = htonl(INADDR_ANY);
2、将套接字转换成监听套接字
len = sizeof(struct sockaddr);
if(bind(listenfd, (struct sockaddr *)&server, len)<0){
perror("bind error.");
    return -1;
}
listen(listenfd, MAX_LISTEN_QUE);
3、等待客户端连接
sockfd = accept(listenfd, (struct sockaddr *)&client, &len);
if(sockfd < 0)
{
perror("accept error.");
return -1;
}
4、读取客户端数据
read(sockfd,buf,100);
printf("%s\n",buf);
5、写据给客户端
time_now = time(NULL);
bzero(&buf,100);
strcpy(buf,(char *)ctime(&time_now));
printf("time:%s\n",buf);
write(sockfd,buf,strlen(buf));
6、关闭套接字
close(sockfd);
close(listenfd);

实例代码:

头文件apue.h

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<strings.h>
#include<time.h>

#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h> //inet

源文件3.c

/*************************************************************************
    > File Name: 3.c
    > Created Time: 2016年12月01日 星期四 10时53分36秒
 ************************************************************************/
/*
 *this is time server
 * */

#include"apue.h"
#define MAX_LISTEN 10
int main(int argc,char *argv[])
{
	int listenfd,sockfd,opt = 1;
	struct sockaddr_in server,client;
	int len;
	time_t time_now;
	char buf[100];

	listenfd = socket(AF_INET,SOCK_STREAM,0);
	if(listenfd<0)
	{
		perror("create socket failed\n");
		return -1;
	}

	if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt))<0)
	{
		perror("set socket reuse addr failed\n");
		return -1;
	}
	
	bzero(&server,sizeof(server));
	server.sin_family = AF_INET;
	server.sin_port = htons(8888);
	server.sin_addr.s_addr = htonl(INADDR_ANY);//代表该主机上的所有IP地址,如果机器上有多个网卡或者虚拟机的话,若不使用此方法容易出错

	len = sizeof(struct sockaddr);
	if(bind(listenfd,(struct sockaddr *)&server,len)<0)
	{
		perror("bind error\n");
		return -1;
	}
	
	listen(listenfd,MAX_LISTEN);//可以连接的最大数据
	
	while(1) //迭代服务器,同时不能连接多个客户端,当一个客户端关闭后就可以重新连接第二个客户端
	{
	sockfd = accept(listenfd,(struct sockaddr *)&client,&len);//sockaddr 和sockaddr_in可以相互转化的
	if(sockfd<0)
	{
		perror("accept error\n");
		return -1;
	}
	
	read(sockfd,buf,100);
	printf("%s\n",buf);

	time_now = time(NULL);
	bzero(&buf,100);
	strcpy(buf,(char *)ctime(&time_now));
	printf("time:%s\n",buf);
	write(sockfd,buf,strlen(buf));
	printf("sockfd:%d\n",sockfd);	
	close(sockfd);
	}
	
	close(listenfd);
	return 0;
}

客户端模型:

1、创建一个IPv4(AF_INET)的字节流(SOCK_STREAM)套接字
int sockfd;
struct sockaddr_in server_ip;
if((sockfd = socket(AF_INET,SOCK_STREAM,0))<0)
{
    perror("socket error\n");
    return -1;
}
2、连接到IP地址为(192.168.1.108、127.0.0.1),端口号为8888的服务器
 bzero(&server_ip,sizeof(server_ip));
//equal to memset()
server_ip.sin_family  =AF_INET;
server_ip.sin_addr.s_addr = inet_addr("127.0.0.1");
server_ip.sin_port = htons(5678);


if(connect(sockfd,(struct sockaddr*)&server_ip,sizeof(server_ip))<0)
{
    perror("connect error\n");
    return 0;
}
3、写一个数据到服务器
strcpy(buf,(char *)"I am client");
if(write(sockfd,buf,strlen(buf))<0)
{
    printf("error,write error\n");
    return -1;
}
4、接收服务器传回来的数据并显示到标准输出
bytes = read(sockfd,buf,100);
if(bytes<0)
{
    printf("error,read failed\n");
    return -1;
}
5、关闭套接字
close(sockfd);

实例代码:

头文件同上;

源文件2.c

/*************************************************************************
    > File Name: 2.c
    > Created Time: 2016年12月01日 星期四 09时52分46秒
 ************************************************************************/
/*
 *this is client to get server time
 * */
#include"apue.h"

int main(int agtc,char *argv[])
{
	int sockfd;
	struct sockaddr_in server_ip;
	char buf[100];
	int bytes;
	if((sockfd = socket(AF_INET,SOCK_STREAM,0))<0)
	{
		perror("socket error\n");
		return -1;
	}

	bzero(&server_ip,sizeof(server_ip));
	//equal to memser()
	server_ip.sin_family  =AF_INET;
	server_ip.sin_addr.s_addr = inet_addr("127.0.0.1");
	server_ip.sin_port = htons(8888);

	if(connect(sockfd,(struct sockaddr*)&server_ip,sizeof(server_ip))<0)
	{
		perror("connect error\n");
		return 0;
	}
	
	bzero(&buf,100);
	strcpy(buf,(char *)"I am client");
	if(write(sockfd,buf,strlen(buf))<0)
	{
		printf("error,write error\n");
		return -1;
	}
	
	bzero(&buf,100);
	bytes = read(sockfd,buf,100);
	if(bytes<0)
	{
		printf("error,read failed\n");
		return -1;
	}

	if(bytes ==0)
	{
		printf("Server close connection\n");
		return -1;
	}

	if(bytes >0)
	{
		printf("read bytes %d\n",bytes);
		printf("time is %s\n",buf);
	}
	
	close(sockfd);
	return 0;
}


注意:server中添加了setsockopt函数
#include <sys/types.h>
#include <sys/socket.h>
int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
如果运行server的时候,若未正常退出内核有时候会提示地址已经在使用,此时可用此函数来重用地址,否则在几分钟内无法重启server的。





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux TCP客户端、服务器编程模型及实例 的相关文章

  • Linux下ps命令实现

    include
  • debian系统配置ip地址

    在Debian中网卡的设置可以通过 etc network interfaces文件来进行 具体可分为三种不同的配置方式 DHCP自动获取 静态分配IP地址和PPPoE宽带拨号 具体设置如下 在进行配置之前 首先进入 etc network
  • 发送arp请求报文

    1 报文格式 2 代码如下 include
  • linux 出错 “INFO: task xxxxxx: 634 blocked for more than 120 seconds.”的3种解决方案

    1 问题描述 最近搭建的一个linux最小系统在运行到241秒时在控制台自动打印如下图信息 并且以后每隔120秒打印一次 仔细阅读打印信息发现关键信息是 hung task timeout secs 第一次遇到这样的问题 首先百度 通过翻看
  • C语言libcurl库的使用

    C语言libcurl库的安装与使用 curl库的作用是访问http和HTTPS网站 HTTPS加密的网站 在linux和树莓派都可以 把curl 7 71 1 tar bz文件复制到linux的工作目录 home lth mkdir htt
  • Linux进程同步机制-Futex

    引子 在编译2 6内核的时候 你会在编译选项中看到 Enable futex support这一项 上网查 有的资料会告诉你 不选这个内核不一定能正确的运行使用glibc的程序 那futex是什么 和glibc又有什么关系呢 futex诞生
  • Linux TCP客户端、服务器编程模型及实例

    Linux TCP客户端 服务器编程模型及实例 服务器模型 1 绑定IPv4的地址 INADDR ANY 和端口号 8888 int listenfd sockfd opt 1 struct sockaddr in server clien
  • EPICS asynPortDriver中数组用法示例

    本驱动程序是继承自asynPortDriver 分别重写了用于读取32位整型数组和32位浮点型数组的 readInt32Array和readFloat32Array 1 源代码如下 arraydriver h include epicsEv
  • DWORD类型

    DWORD 类型基本相关 DWORD 宏定义 typedef unsigned long DWORD 1 要使用DWORD要添加头文件
  • linux读取触摸屏事件数据

    对于有触摸设备的电脑或者手机 通过cat proc bus input devices应该就能够看到触摸设备的相关信息 比如 cat proc bus input devices I Bus 0013 Vendor 0x0012 Produ
  • C语言实现成语接龙完整版

    C语言实现成语接龙报告完整版 代码在最后面 实验报告书 实验名称 成语接龙人机对战游戏 摘要 成语接龙是中华民族传统的文字游戏 它有着悠久的历史 也有广泛的社会基础 是老少皆宜的民间文化娱乐活动 同时成语又是体现我国文字 文化 文明的一个缩
  • LRC歌词解析,实现Linux设备播放音乐显示歌词 LRC解析

    开始正文 1 关于LRC lrc是英文lyric 歌词 的缩写 被用做歌词文件的扩展名 以lrc为扩展名的歌词文件可以在各类数码播放器中同步显示 LRC 歌词是一种包含着 形式的 标签 tag 的 基于纯文本的歌词专用格式 最早由郭祥祥先生
  • linux下添加cmath库

    在Terminal下输入g sqrt c lm即可
  • ubuntu下学习c++(输出定义变量)

    2022 6 11 学习cout cin的使用方法以及变量的定义 include
  • C语言void指针及使用注意事项详解

    void 指针是一种特殊的指针 表示为 无类型指针 在 ANSI C 中使用它来代替 char 作为通用指针的类型 由于 void 指针没有特定的类型 因此它可以指向任何类型的数据 也就是说 任何类型的指针都可以直接赋值给 void 指针
  • Linux C编程基础:获取时间

    1 前言 对于linux下的编程 无论是用户态还是内核态 时间获取都是经常需要使用到的 以下分别从用户态和内核态整理了几个常用的时间获取接口 供编写代码时快速查阅 linux时间子系统的发展历史及详细介绍 可以参考 深入理解Linux时间子
  • gdb调试心得体会

    gdb调试心得体会 首先进入gdb 调试二进制程序 gdb msgsvr dev 然后 运行 run 然后coredump了 输入bt查看调用栈 bt 然后查看函数栈 f 进入到指定的函数 然后查看具体行数 l number 然后break
  • sbrk/brk函数用法

    头文件unistd h sbrk brk函数重新指定数据段的结束位置 sbrk 0 获得当前数据段结束地址 sbrk 增量 增量可正 可负 可为0 都返回原来数据段的结束地址 失败返回 1 brk 地址 返回0或 1 通过重新指定数据段新的
  • LinuxC中进程通信

    LinuxC中进程通信 信号 Signals Linux 提供了信号机制 允许一个进程向另一个进程发送信号以通知特定事件的发生 这是一种轻量级的通信机制 通常用于处理异步事件 您可以使用 kill 命令或 kill 函数来发送信号 然后使用
  • unistd.h中定义的setsid()与fork()

    setsid 是一个UNIX系统调用 用于创建一个新的会话 session 并将当前进程设置为该会话的领头进程 session leader 通常情况下 setsid 函数用于创建守护进程 daemon 以确保它与任何终端分离 从而可以在后

随机推荐