socket在Linux下小Demo

Ubuntu的终端用来搞c和c++真是太方便了,哪像windows下的turboC那么麻烦啊!

 

直接vi编辑一个.c 或 .cpp 文件,然后g++ 或 gcc 一编译,直接  ./a.out运行,真是太方便了。

 

不熟悉的函数直接man一下就ok了。好东西啊!

 

 

现在就用这东西学习一下socket吧:

 

1.首先搞一个服务端:

 

vi a.c

 

内容如下:

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 引入的三个头文件,是必需的:
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
// 两个结构体,下面要用的,实例化了?NO,没有实例化
// 只是重命名了,为什么要这样呢?
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR ;

// 入口main,注意参数,这个是要输入的启动参数,
// 例如:./service 9999,其中9999就是输入的参数
// 是个char数组,可以传入多个参数,按顺序
int main(int argc,char **argv)
{

        // 1.创建套接字
        // 参数:SOCK_DGRAM是基于UDP的socket通信模式,
        // 如果是TCP的话是SOCK_STREAM.
	int fd = socket(AF_INET, SOCK_DGRAM, 0);
	
	// 声明一个服务端和一个客户端的结构体对象:
	SOCKADDR_IN addrSrv ;
	SOCKADDR_IN addrClient;

	// 定义接收和发送的字符串
	char  recvBuf[100] = {0};
	char  sendBuf[100] = {0};

        // 服务端的长度,下面要用到
	int len = sizeof(addrSrv);

	// 服务端的地址,
 	// INADDR_ANY 可接受的客户端是任意地址
	addrSrv.sin_addr.s_addr = htonl(INADDR_ANY);
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(atoi(argv[1]));// 服务端的端口号

	// 绑定套接字和端口
	bind(fd,(struct sockaddr *)&addrSrv,sizeof(addrSrv));


	while(1){
		// 接收客户端信息
		recvfrom(fd, recvBuf, 16, 0, (SOCKADDR*)&addrClient, &len);
		printf("recvBuf :%s\n",recvBuf);

		printf("please input data:\n");
		fgets(sendBuf,100,stdin);
		// 发送给客户端信息
		sendto(fd,sendBuf,20,0,(SOCKADDR*)&addrClient, len);

	}

	// 关闭套接字
	close(fd);
	// 可以有或没有return 1;

}
 

 

2.构建一个客户端:

 

vi b.c

 

代码如下:

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 引入的三个头文件,是必需的:
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>

typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR ;
int main(int argc,char **argv)
{
	int fd = socket(AF_INET, SOCK_DGRAM, 0);
	SOCKADDR_IN addrSrv ;
	SOCKADDR_IN addrClient;
	char  recvBuf[100] = {0};
	char  sendBuf[100] = {0};
	int len = sizeof(addrClient);

	// 此处的输入的第二个参数是指定服务端的ip地址
	addrSrv.sin_addr.s_addr = inet_addr(argv[2]);
	addrSrv.sin_family = AF_INET;
        // 输入的第一个参数,服务端的端口号
	addrSrv.sin_port = htons(atoi(argv[1]));

// 跟服务端的不同之处,不用绑定套接字和端口
//	bind(fd,(struct sockaddr *)&addrSrv,sizeof(addrSrv));

	while(1)
	{
		printf("please inpur data\n");
		fgets(sendBuf,100,stdin);
		sendto(fd,sendBuf,20,0,(SOCKADDR*)&addrSrv, len);
		recvfrom(fd, recvBuf, 16, 0, (SOCKADDR*)&addrClient, &len);
		printf("recvBuf %s\n",recvBuf);
	}

	close(fd);
	return 0;
}
 

两者差别不多,只两点:1.客户端需要指定服务端的ip和端口,所以执行的时候需要输入端口和ip。

 

                                            2.客户端不需要绑定端口。

 

 

3.编译:

 

gcc a.c -o server

 

 

gcc b.c -o client

 

 

4.运行:

 

./server 9999

 

从另一个终端运行:

 

./client  9999 192.168.*.*

 

 

5.结果,不同的终端代表不同的进程,通过输入和打印出的信息就能证明两者开始交互了。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的示例代码,演示了如何在Linux C++中接收protobuf消息并进行解码: ```cpp #include <iostream> #include <string> #include <netinet/in.h> #include <sys/socket.h> #include <arpa/inet.h> #include "my_proto.pb.h" using namespace std; int main() { int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { cerr << "socket error!" << endl; exit(-1); } struct sockaddr_in servaddr; bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(8080); servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) { cerr << "connect error!" << endl; exit(-1); } char buffer[1024]; int n = read(sockfd, buffer, sizeof(buffer)); if (n < 0) { cerr << "read error!" << endl; exit(-1); } MyProto my_proto; if (!my_proto.ParseFromArray(buffer, n)) { cerr << "protobuf parse error!" << endl; exit(-1); } cout << "message: " << my_proto.message() << endl; close(sockfd); return 0; } ``` 这里假设我们已经定义了名为`MyProto`的protobuf消息类型,并将其编码后发送给了本机的8080端口。在客户端中,我们首先创建一个Socket套接字,并将其连接到服务器。然后,我们从Socket中读取数据,并将其存储在名为`buffer`的字符数组中。接下来,我们使用`ParseFromArray`函数将`buffer`中的数据解析为protobuf消息。最后,我们打印出消息中的内容,并关闭Socket连接。 请注意,上述代码仅为演示目的,并未进行错误处理或异常情况处理。在实际应用中,你需要根据具体情况进行适当的错误处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值