linux下socket三种方式简单例子

udp:

1、建立socket套接字
2、servaddr初始化(比如端口号)
3、bind 绑定servaddr

4、recvform或者sendto函数调用(也可以用tcp的收发函数,send,read,write)

下面的例子是简单的回射功能,只作用一次。

代码:

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

#define PORT  8080

int main(void)
{
	int fd;
	int flag;
	fd = socket(AF_INET,SOCK_DGRAM,0);
	if(fd<0){
		printf("error in open socket\n");
		exit(1);
	}

	struct sockaddr_in servaddr,cliaddr;
	bzero(&servaddr,0);
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(PORT);//端口号
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//udp的话这个可以any
	flag = bind(fd,(struct sockaddr *)&servaddr,sizeof(struct sockaddr));//绑定
	if(flag<0){
		printf("error in bind\n");
		exit(1);
	}

	char buf[128];
	memset(buf,0,sizeof(buf));
	int len = sizeof(cliaddr);
	int n;
	n = recvfrom(fd,buf,128,0,(struct sockaddr *)&cliaddr,&len);//接收
	printf("receive buf:%s\n",buf);

	sendto(fd,buf,n,0,(struct sockaddr *)&cliaddr,len);//回射回去

	return 0;
}

TCP服务器:

1、建立socket套接字(SOCK_STREAM:tcp)
2、初始化服务器sockaddr_in参数(主要是端口号,以及类型)
3、应考虑下tcp的重置向—— rc = setsockoptsockfd,SOL_SOCKET,  SO_REUSEADDR,  (char *)&on, sizeof(on)); int on=1;
4、bind地址
5、监听(listen),把进程转化为一个服务器。
int listen(int sockfd, int backlog);  backlog为连接请求队列的最大长度(一般由2到6,一般取5)
6、accept。将从连接请求队列中获得连接信息,创建新的套接字(新的fd),提取最前的一个客户请求
 int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 
这的addr为客户端的sockaddr_in
7、fork出子进程,用于发送给客户端信息。

代码:

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

#define PORT  5000
int main(void)
{
	int fd;
	struct sockaddr_in servaddr,cliaddr;
	int flag;

	fd = socket(AF_INET,SOCK_STREAM,0);
	if(fd<0){
		printf("error in socket\n");
		return 0;
	}
	
	/* init servaddr */
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(PORT);  //端口
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);  //服务器的话,这个是any

	int on=1;
	flag = setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&on,sizeof(on));  //重置向
	if(flag<0){
		printf("error in reuseaddr\n");
		exit(1);
	}

	flag = bind(fd,(struct sockaddr *)&servaddr,sizeof(servaddr));   //绑定
	if(flag<0){
		printf("error in bind\n");
		exit(1);
	}

	flag = listen(fd,5);   //开启监听
	if(flag<0){
		printf("error in listen\n");
		exit(1);
	}
	
	int len = sizeof(servaddr);
	int cfd;
	while(1){
		if((cfd=accept(fd,(struct sockaddr *)&cliaddr,&len))>=0);  //等待客户端连接,创建新套接字
		if(fork() == 0){
			close(fd);  //这个已经没必要存在了
			while(1){
				char buf[128];
				memset(buf,0,sizeof(buf));
				int n = 0;
				//n = read(cfd,buf,128);  //这个也是可以用的
				n = recv(cfd,buf,128,0);   //用这个,很多书上都用这个
				if(n<0){
					exit(1);
				}
				write(cfd,buf,n);
			}
		}
	}

}

TCP客户端

1、建立socket套接字(SOCK_STREAM:tcp)
2、初始化服务器的sockaddr_in,特别是端口号以及服务器ip地址
3、connect。尝试建立与服务器的连接。
int connect (int sockfd,struct sockaddr * serv_addr,int addrlen); 
sockaddr为服务器地址信息
4、send or recv  操作。

代码:

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

#define PORT  5000
int main(void)
{
	int fd;
	struct sockaddr_in servaddr;

	fd = socket(AF_INET,SOCK_STREAM,0);
	if(fd<0){
		printf("error in socket\n");
		return 0;
	}
	
	/* init servaddr */
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(PORT);
	if(inet_pton(AF_INET, "172.31.18.207", &servaddr.sin_addr) <= 0){  //服务器的ip要初始化
		printf("is not a valid IPaddress/n");
		return 0;
	}

	/* connect to server */
	int i;
	for(i=0;i<5;i++){
		if(connect(fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1){  //去链接服务器
			perror("connect error");
			continue;
		}
		break;
	}	

	char buf[128];
	memset(buf,0,sizeof(buf));
	int n = 0;
//	n = read(fd,buf,128);
	n = recv(fd,buf,128,0);
	printf("receive:buf:%s\n",buf);

	write(fd,buf,n);

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值