C语言实现TCP通信(服务端与客户端)

在这里插入图片描述
服务器

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(){
    //创建套接字
	/*
	int socket(int af, int type, int protocol);
	af:地址族 常用的有 AF_INET(IPv4 地址) 和 AF_INET6(IPv6)
	type:数据传输方式常用的有 SOCK_STREAM 和 SOCK_DGRAM
    protocol:传输协议,常用的有 IPPROTO_TCP(TCP 传输协议) 和 IPPTOTO_UDP(UDP 传输协议)
	返回值:非负描述符 – 成功,-1 - 出错
	*/
    int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    //将套接字和IP、端口绑定
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
    serv_addr.sin_family = AF_INET;  //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("192.168.183.138");  //具体的IP地址
    serv_addr.sin_port = htons(1234);  //端口
    bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    //进入监听状态,等待用户发起请求
	/*
	int listen(int sock, int backlog); 
	sock:为需要进入监听状态的套接字
	backlog:为请求队列的最大长度
	*/
    listen(serv_sock, 20);
    //接收客户端请求
    struct sockaddr_in clnt_addr;
    socklen_t clnt_addr_size = sizeof(clnt_addr);
    int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);
    //向客户端发送数据
    char str[] = "Hello World!";
    write(clnt_sock, str, sizeof(str));
 
    //关闭套接字
    close(clnt_sock);
    close(serv_sock);
    return 0;
}

客户端

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main(){
    //创建套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    //向服务器(特定的IP和端口)发起请求
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
    serv_addr.sin_family = AF_INET;  //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址
    serv_addr.sin_port = htons(1234);  //端口
    connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
 
    //读取服务器传回的数据
    char buffer[40];
    read(sock, buffer, sizeof(buffer)-1);
 
    printf("Message form server: %s\n", buffer);
 
    //关闭套接字
    close(sock);
    return 0;
}

tcpClient.c

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

int main(int argc, char *argv[])
{
	if(3 != argc)
	{
		printf("%s <IP> <PORT>\n", argv[0]);
		return -1;
	}

	//1. 申请网卡
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == sockfd)
	{
		perror("socket");
		return -1;
	}
	
	//2. 连接服务器
	struct sockaddr_in serveraddr = {0};
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
	serveraddr.sin_port = htons(atoi(argv[2]));
	if(-1 == connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)))
	{
		perror("connect");
		return -1;
	}

	while(1)
	{	
		char buf[100] = {0};
		printf("input> ");fflush(stdout);
		gets(buf);
		//3. 发请求
		write(sockfd, buf, 100);

		//4. 收反馈
		bzero(buf, 100);
		read(sockfd, buf, 100);
		printf("recv: %s\n", buf);
	}
	//5. 断开连接
	close(sockfd);
}

tcpServer.c

#include <stdio.h>
#include <sys/types.h>        
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <asm/ioctl.h>

#define PWMON  _IO('P', 0)
#define PWMOFF _IO('P', 1)
#define PWMSET _IO('P', 2)
#define LEDON _IO('L',0)
#define LEDOFF _IO('L',2)
#define TYPE 'c'
#define temp_9  _IO(TYPE,0)
#define temp_10 _IO(TYPE,1)
#define temp_11 _IO(TYPE,2)
#define temp_12 _IO(TYPE,3)
#define PATH "/dev/ds18b20"

int main()
{
	//1. 申请网卡
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == sockfd)
	{
		perror("socket");
		return -1;
	}
	
	//2. 准备被客户端连接
	struct sockaddr_in serveraddr = {0};
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_addr.s_addr = inet_addr("0.0.0.0");
	serveraddr.sin_port = htons(8886);
	if(-1 == bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)))
	{
		perror("connect");
		return -1;
	}
	
	//3.监听
	listen(sockfd, 10);

	//4. 提取接入
	int clientfd = accept(sockfd, NULL, NULL);

	
	int fdl = open("/dev/led0", O_RDWR);	

	
	int fdt;
    short temp;
    char zheng,fen;
    float temputer,resolution;
    fdt = open(PATH,O_RDWR);
    if(fdt < 0){
            perror("open");
            return -1;
    }
    if(ioctl(fdt,temp_12,&resolution))
    {
            perror("ioctl \n");
            return -1;
    }

	while(1)
	{
		//5. 收请求
		char buf[30] = {0};
		read(clientfd, buf, 100);
		printf("recv: %s\n", buf);

		switch(buf[0])
		{
		case '1':
			//beep on
			ioctl(fdl, LEDON);
			break;
		case '2':
			//beep off
			ioctl(fdl, LEDOFF);
			break;
		case '3':
			if(!read(fdt,&temp,sizeof(short))){
                perror("read");
            }
            zheng = temp>>4;
            fen = temp & 0xf;
            if(zheng & (1<<8)){
                    temputer = (temp - 65535) * resolution;
            }else{
                    temputer = zheng + fen * resolution;
            }
            if((temputer >= (-55)) && (temputer <= 125))
                    sprintf(buf,"tempter:%0.3f\n",temputer);
		}
		//6. 发反馈
		write(clientfd, buf, 100);
	}
	//7. 断开连接
	close(sockfd);
	close(clientfd);
	close(fdt);
}

camera_server.c

int main(int argc, char **argv)
{
	if(2 != argc)
	{
		printf("Usage: %s <video>\n", argv[0]);
		return -1;
	}
	
	int i;
	int fd;
	int ret;
	unsigned int width;
	unsigned int height;
	unsigned int size;
	unsigned int index;
	unsigned int ismjpeg;

	width = 640;
	height = 480;
	
	//1. 打开并初始化摄像头
	fd = camera_init(argv[1], &width, &height, &size, &ismjpeg);
	if (fd == -1)
		return -1;
	ret = camera_start(fd);
	if (ret == -1)
		return -1;
	
	//2. 采集几张图片丢弃 
	char *jpeg_ptr = NULL;
	for (i = 0; i < 8; i++) {
		ret = camera_dqbuf(fd, (void **)&jpeg_ptr, &size, &index);
		if (ret == -1)
			exit(EXIT_FAILURE);

		ret = camera_eqbuf(fd, index);
		if (ret == -1)
			exit(EXIT_FAILURE);
	}

	fprintf(stdout, "init camera success\n");

	//等着客户端连上来
	//1. 申请网卡
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == sockfd)
	{
		perror("socket");
		return -1;
	}
	
	//2. 准备被客户端连接
	struct sockaddr_in serveraddr = {0};
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_addr.s_addr = inet_addr("0.0.0.0");
	serveraddr.sin_port = htons(8888);
	if(-1 == bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)))
	{
		perror("connect");
		return -1;
	}
	
	//3.监听
	listen(sockfd, 10);

	//4. 提取接入
	int clientfd = accept(sockfd, NULL, NULL);

	while(1)
	{

		//3. 提取摄像头的一帧
		ret = camera_dqbuf(fd, (void **)&jpeg_ptr, &size, &index); //tack picture
		if (ret == -1)
			return -1;
		
		printf("taking one!\n");
		
		//发给客户端
		//a.发大小
		char buf[10] = {0};
		sprintf(buf, "%d", size);//将printf("%d",size)的输出结果送给buf
		
		/*
		int write(int handle,void *buf,int len);
		int handle:获取文件指针的文件句柄
        		void *buf:写入的内容
       		 int len:写入文件的长度
		*/		
		write(clientfd, buf, 10);

		//b. 发内容
		int ret = write(clientfd, jpeg_ptr, size);
		printf("size: %d\n", ret);
		/*
		//4. 创建一个空白文件
		int pixfd = open("1.jpg", O_WRONLY|O_CREAT, 0666);

		//5. 将摄像头数据写入文件(发出去jpeg_ptr数组起始位置size数组大小)
		write(pixfd, jpeg_ptr, size);
		
		//测试用
		break;
		*/

		//6. 确认已经取走
		ret = camera_eqbuf(fd, index); //prepare for next tacking
		if (ret == -1)
			return -1;
	}

	//7. 关掉摄像头
	ret = camera_stop(fd); //stop the camera!!!! do not call this!!!
	if (ret == -1)
		return -1;

	//8. 退出摄录
	ret = camera_exit(fd);
	if (ret == -1)
		return -1;
}

camera_client

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLabel>
#include <QTcpSocket>
#include <QDebug>

class Widget : public QWidget
{
    Q_OBJECT
public slots:
    void readpix()
    {
        if(readsize)//读大小
        {
            //1. 接照片大小
            char sizebuf[10] = {0};
            sock->read(sizebuf, sizeof(sizebuf));
            size = atoi(sizebuf);
            qDebug()<<size;

            readsize = false;
        }
        else
        if(sock->bytesAvailable() >= size)//照片完全到达
        {
            //2. 接收照片内容
            char buf[640*480*3] = {0};
            int ret = sock->read(buf, size);
            qDebug()<<ret;

            //3. 显示照片
            QPixmap a;
            a.loadFromData((uchar*)buf, size);
            lb->setPixmap(a);
            readsize = true;
        }
    }

public:
    Widget(QWidget *parent = 0);
    ~Widget();

    QLabel *lb;

    QTcpSocket *sock;
    bool readsize;
    int size;
};

#endif // WIDGET_H

  • 10
    点赞
  • 109
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用libevent库实现TCP/IP客户端服务端通信,可以按照以下步骤进行: 1. 引入libevent库的头文件和链接库。 ```c #include <event2/event.h> #include <event2/bufferevent.h> #include <event2/buffer.h> #include <event2/listener.h> #include <event2/util.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/socket.h> #include <fcntl.h> #pragma comment(lib, "event.lib") #pragma comment(lib, "event_core.lib") #pragma comment(lib, "event_extra.lib") ``` 2. 创建服务端监听器并设置回调函数。 ```c struct event_base* base = event_base_new(); // 创建event_base对象 // 创建监听器 struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(8888); struct evconnlistener* listener = evconnlistener_new_bind(base, accept_cb, NULL, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, 10, (struct sockaddr*)&sin, sizeof(sin)); // 设置回调函数 void accept_cb(struct evconnlistener* listener, evutil_socket_t fd, struct sockaddr* addr, int len, void* ptr) { struct event_base* base = evconnlistener_get_base(listener); struct bufferevent* bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(bev, read_cb, NULL, event_cb, NULL); bufferevent_enable(bev, EV_READ | EV_WRITE); } ``` 3. 创建客户端并连接到服务端。 ```c struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(8888); inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr); // 创建事件对象 struct event_base* base = event_base_new(); struct bufferevent* bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(bev, read_cb, NULL, event_cb, NULL); // 连接服务端 bufferevent_socket_connect(bev, (struct sockaddr*)&sin, sizeof(sin)); ``` 4. 设置读回调函数。 ```c void read_cb(struct bufferevent* bev, void* ctx) { struct evbuffer* input = bufferevent_get_input(bev); size_t len = evbuffer_get_length(input); char* data = (char*)malloc(len + 1); memset(data, 0, len + 1); evbuffer_copyout(input, data, len); printf("recv: %s\n", data); free(data); evbuffer_drain(input, len); } void event_cb(struct bufferevent* bev, short events, void* ctx) { if (events & BEV_EVENT_EOF) { printf("connection closed\n"); } else if (events & BEV_EVENT_ERROR) { printf("some other error\n"); } bufferevent_free(bev); } ``` 5. 启动事件循环。 ```c event_base_dispatch(base); ``` 这样就可以使用libevent库实现TCP/IP客户端服务端通信了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值