• 简单的Linux下的socket通信,小程序,方便以后查看。


    首先是我的一个出错提示的头文件<myerr.h>,自从用了根本停不下来啊!!!

    #ifndef			_MYERR_H_
    #define			_MYERR_H_
    
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    extern int errno;
    
    #define MYDBG
    
    #ifdef MYDBG
    #define PRN_ERRMSG_EXIT(errmsg) 
    	({ 
    		fprintf(stderr, "Say->%s : File->%s : Line->%d : Fun->%s : Cause->%s
    
    ", 
    			errmsg,__FILE__,__LINE__,__func__,strerror(errno)); 
    			exit(-1); 
    	})
    #else
    #define PRN_ERRMSG_EXIT(errmsg) ({exit(-1);})
    #endif
    
    #ifdef MYDBG
    #define PRN_ERRMSG_RETURN(errmsg) 
    	({ 
    		fprintf(stderr, "Say->%s : File->%s : Line->%d : Fun->%s : Cause->%s
    
    ", 
    			errmsg,__FILE__,__LINE__,__func__,strerror(errno)); 
    			return(-1); 
    	})
    #else
    #define PRN_ERRMSG_RETURN(errmsg) ({return(-1);})
    #endif
    
    #ifdef MYDBG
    #define PRN_ERRMSG(errmsg) 
    	({ 
    		fprintf(stderr, "Say->%s : File->%s : Line->%d : Fun->%s : Cause->%s
    
    ", 
    			errmsg,__FILE__,__LINE__,__func__,strerror(errno)); 
    	})
    #else
    #define PRN_ERRMSG(errmsg)
    #endif
    
    #ifdef MYDBG
    #define ASSERT(EXP) 
    	({
    		if(!(EXP)){
    		fprintf(stderr, "Say->%s : File->%s : Line->%d : Fun->%s : Cause->%s
    
    ", 
    				__FILE__,__LINE__,__func__,strerror(errno)); 
    				exit(-1); 
    		}
    	})
    #else
    #define ASSERT(EXP)
    #endif
    
    #endif		   //_ERROR_H_
    

    然后就是我编写的简便代码,方便其他地方调用额。<socket.c>

    #include "mysocket.h"
    
    int ser_socket(const char *ipstr, const unsigned short port)
    {
    	/*创建一个流式套接字*/
    	int s = socket(PF_INET, SOCK_STREAM, 0);
    	if (0 > s)
    		PRN_ERRMSG_RETURN("socket");
    
    	int on = 1;
    	if (0 > setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
    		PRN_ERRMSG_RETURN("setsockopt");
    
    	struct sockaddr_in addr = {
    		.sin_family		 =	PF_INET,
    		.sin_port		 =	htons(port),
    		.sin_addr.s_addr =	(NULL==ipstr)?INADDR_ANY:inet_addr(ipstr),
    	};
    
    	memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
    	if (0 > bind(s, (struct sockaddr*)&addr, sizeof(struct sockaddr)))
    		PRN_ERRMSG_RETURN("bind");
    
    	if (0 > listen(s, BACKLOG))
    		PRN_ERRMSG_RETURN("listen");
    
    	return s;
    }
    
    int cli_socket(const char *ipstr, const unsigned short port)
    {
    	/*创建一个流式套接字*/
    	int s = socket(PF_INET, SOCK_STREAM, 0);
    	if (0 > s)
    		PRN_ERRMSG_RETURN("socket");
    
    	struct sockaddr_in addr = {
    		.sin_family		 =	PF_INET,
    		.sin_port		 =	htons(port),
    		.sin_addr.s_addr =	inet_addr(ipstr),
    	};
    
    	memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
    	if (0 > connect(s, (struct sockaddr*)&addr, sizeof(struct sockaddr)))
    		PRN_ERRMSG_RETURN("connect");
    
    	return s;
    }
    
    int my_accept(int sockFd, struct sockaddr_in *addr)
    {
    	socklen_t len = sizeof(struct sockaddr_in);
    	memset(addr, 0, len); // 将结构体清零
    	int rws = accept(sockFd, (struct sockaddr*)addr, &len);
    	if (0 > rws)
    		PRN_ERRMSG_RETURN("accept");
    
    	return rws;
    }
    

    当然也要为这个文件编写头文件了。。。<mysocket.h>

    #ifndef		_SOCKET_H_
    #define		_SOCKET_H_
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #include <sys/types.h>          /* See NOTES */
    #include <sys/socket.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    #include <myerr.h>
    
    #define BACKLOG		5		/* length of listening queue on socket */
    
    /*
     * 服务器开启服务
     * ipstr : 服务器ip
     * port  : 绑定的端口
     * 返回  : 一个网络套接字
     */
    int ser_socket(const char *ipstr, const unsigned short port);
    /*
     * 客户端连接服务器
     * ipstr : 服务器ip
     * port  : 服务器的端口
     * 返回  : 一个网络套接字
     */
    int cli_socket(const char *ipstr, const unsigned short port);
    /*
     * 等待客户端连接
     * sockFd  : 套接字
     * addr    : 接收客户端信息
     * 返回    : 与客户端通信的文件描述副
     */
    int my_accept(int sockFd, struct sockaddr_in *addr);
    
    #endif	   //_SOCKET_H_
    

    然后就是服务器的代码了。<main_ser.c>

    #include "mysocket.h"
    
    
    int main(int argc,char *argv[])
    {
    	int serFd = ser_socket(NULL, 8888);
    	struct sockaddr_in addr;
    	char buffer[1024];
    	while (1) {
    		int accFd = my_accept(serFd, &addr);
    		while (1) {
    			memset(buffer, 0, 1024);
    			if (0 >= recv(accFd, buffer, 1024, 0)) {
    				PRN_ERRMSG("recv");
    				close(accFd);
    				break;
    			}
    			printf("client : %s
    ", buffer);
    			if (0 > send(accFd, buffer, strlen(buffer), 0)) {
    				PRN_ERRMSG("recv");
    				close(accFd);
    				break;
    			}
    		}
    	}
    	return 0;
    }
    

    然后就是客户端的代码了<main_cli.c>

    #include "mysocket.h"
    
    int main(int argc,char *argv[])
    {
    	int sockFd = cli_socket("127.0.0.1", 8888);
    	char buffer[1024];
    	while (1) {
    		printf("input :");
    		fgets(buffer, 1024, stdin);
    		*strchr(buffer, '
    ') = '';// 采用这种方法可以避免输入超出缓冲区
    		if (0 > send(sockFd, buffer, strlen(buffer), 0)) {
    			PRN_ERRMSG("recv");
    			close(sockFd);
    			break;
    		}
    		memset(buffer, 0, 1024);
    		if (0 >= recv(sockFd, buffer, 1024, 0)) {
    			PRN_ERRMSG("recv");
    			close(sockFd);
    			break;
    		}
    		printf("server : %s
    ", buffer);
    	}
    	return 0;
    }
    

    好啦。。以后需要用的时候再来看看额。。。

    作者:janbar
    本文版权归作者和博客园所有,欢迎转载,转载请标明出处。喜欢我的文章请 [关注我] 吧。
    如果您觉得本篇博文对您有所收获,可点击 [推荐] [收藏] ,或到右侧 [打赏] 里请我喝杯咖啡,非常感谢。
  • 相关阅读:
    MySQL 快速删除大量数据(千万级别)的几种实践方案——附源码
    Elasticsearch 通过Scroll遍历索引,构造pandas dataframe 【Python多进程实现】
    MySQL LOAD DATA INFILE—从文件(csv、txt)批量导入数据
    【Java】 NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException、ArrayIndexOutOfBoundsException、ArrayStoreException、ArithmeticException等没有异常堆栈信息
    技术人“结构化思维”训练的一点想法和实践
    gitlab内存消耗大,频繁出现502错误的解决办法
    Tesseract-OCR 4.1.0 安装和使用— windows及CentOS
    Tika结合Tesseract-OCR 实现光学汉字识别(简体、宋体的识别率百分之百)—附Java源码、测试数据和训练集下载地址
    记一次Elasticsearch OOM(内存溢出)的优化过程—基于segments force merge 和 store type 转为 hybridfs
    ElasticSearch如何一次查询出全部数据——基于Scroll
  • 原文地址:https://www.cnblogs.com/janbar/p/13698985.html
Copyright © 2020-2023  润新知