C语言 socket编程实例

一. 面向连接的流式套接字 C/S 例子

在树莓派下,新建一个 Server1.c,命令 nano Server1.c,然后写入如下内容

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <arpa/inet.h> 
#include <sys/wait.h> 
#include <signal.h> 
#define PORT "9090" // the port users will be connecting to 
#define BACKLOG 10 
// how many pending connections queue will hold 
void sigchld_handler(int s) 
{
    
	while(waitpid(-1, NULL, WNOHANG) > 0); 
}
// get sockaddr, IPv4 or IPv6: 
void *get_in_addr(struct sockaddr *sa) 
{
    
    if (sa->sa_family == AF_INET) {
    
    	return &(((struct sockaddr_in*)sa)->sin_addr); 
    }
	return &(((struct sockaddr_in6*)sa)->sin6_addr); 
}
int main(void) 
{
    
    int sockfd, new_fd; // listen on sock_fd, new connection on new_fd 
    struct addrinfo hints, *servinfo, *p; 
    struct sockaddr_storage their_addr; // connector's address information 
    socklen_t sin_size; 
    struct sigaction sa; 
    int yes=1;
    char s[INET6_ADDRSTRLEN]; 
    int rv; 
    memset(&hints, 0, sizeof hints); 
    hints.ai_family = AF_UNSPEC; 
    hints.ai_socktype = SOCK_STREAM; 
    hints.ai_flags = AI_PASSIVE; // use my IP 
    if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
    
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 
        return 1; 
	}
// loop through all the results and bind to the first we can 
    for(p = servinfo; p != NULL; p = p->ai_next) {
    
    if ((sockfd = socket(p->ai_family, p->ai_socktype, 
    p->ai_protocol)) == -1) {
    
        perror("server: socket"); 
        continue; 
    }
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, 
    sizeof(int)) == -1) {
    
        perror("setsockopt"); 
        exit(1); 
    }
    if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
    
        close(sockfd); 
        perror("server: bind"); 
        continue; 
    }
    break; 
}
    if (p == NULL) {
    
        fprintf(stderr, "server: failed to bind\n"); 
        return 2; 
    }
    freeaddrinfo(servinfo); // all done with this structure 
    if (listen(sockfd, BACKLOG) == -1) {
    
        perror("listen"); 
        exit(1); 
    }
    sa.sa_handler = sigchld_handler; // reap all dead processes 
    sigemptyset(&sa.sa_mask); 
    sa.sa_flags = SA_RESTART; 
    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
    
        perror("sigaction"); 
        exit(1); 
    }
    printf("server: waiting for connections...\n"); 
    while(1) {
    // main accept() loop 
        sin_size = sizeof their_addr; 
        new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); 
        if (new_fd == -1) {
    
            perror("accept"); 
            continue; 
        }
        inet_ntop(their_addr.ss_family, 
        get_in_addr((struct sockaddr *)&their_addr), 
        s, sizeof s); 
        printf("server: got connection from %s\n", s); 
        if (!fork()) {
    // this is the child process 
            close(sockfd); // child doesn't need the listener 
            if (send(new_fd, "Hello, world!", 13, 0) == -1) 
            perror("send"); 
            close(new_fd); 
            exit(0); 
        }
        close(new_fd); // parent doesn't need this 
    }
    return 0; 
}

然后编译并运行

gcc Server1.c -o Server1
./Server1

在Ubuntu系统下,新建一个Client1.c文件,命令gedit Client1.c,然后写入如下内容

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

#define PORT "9090"  //the port client will be connecting to
#define MAXDATASIZE 100  //max number of bytes we can get at once

//get sockaddr, IPv4 or IPv6
void *get_in_addr(struct sockaddr *sa)
{
   
	if(sa->sa_family == AF_INET)
	{
   
		return &(((struct sockaddr_in*)sa)->sin_addr);
	}
	return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(int argc, char *argv[])
{
   
	int sockfd, numbytes;
	char buf[MAXDATASIZE];
	struct addrinfo hints, *servinfo, *p;
	int rv;
	char s[INET6_ADDRSTRLEN];
	if(argc != 2)
	{
   
		fprintf(stderr, "usage:client hostname\n");
		exit(1);
	}
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	if((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0)
	{
   
		fprintf(stderr, "getaddrinfo:%s\n",gai_strerror(rv));
		return 1;
	}
    // loop through all the results and connect to the first we can 
	for(p = servinfo; p != NULL; p = p->ai_next)
	{
   
		if((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
		{
   
			perror("client:socket");
			continue;
		}
		if(connect(sockfd, p->ai_addr, p->ai_addrlen) == -1)
		{
   
			close(sockfd);
			perror("client:connect");
			continue;
		}
		break;
	}
	if(p == NULL)
	{
   
		fprintf(stderr, "client:failed to connect\n");
		return 2;
	}
	inet_ntop(p->ai_family, get_in_addr((struct sockaddr*)p->ai_addr), s, sizeof s);
	printf("client:connecting to %s\n",s);
	freeaddrinfo(servinfo);// all done with this structure 
	if((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1)
	{
   
		perror("recv");
		exit(1);
	}
	buf[numbytes] = '\0';
	printf("client:received %s\n",buf);
	close(sockfd);
	return 0;
}
gcc Client1.c -o Client1
./Client1 192.168.43.161
# 二级目录

二. 非阻塞的多人聊天服务器端例子

在树莓派下,新建一个Server2.c文件,命令nano Server2.c,然后写入如下内容

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

#define PORT "9090"  //port we're listening on

//get sockaddr,IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
   
    if(sa->sa_family == AF_INET){
   
        return &(((struct sockaddr_in*)sa)-
  • 0
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VS是微软公司开发的一款集成开发环境,而libcurl、zlib和openssl都是开源软件库。 libcurl是一个用于支持网页传输协议的客户端软件库。它支持多种传输协议,包括HTTP、FTP、SMTP等,可以方便地实现网络数据的传输和通信。libcurl提供了简单易用的API接口,具有高度的可移植性和灵活性,广泛应用于各种网络应用中。 zlib是一个用于数据压缩和解压缩的库。它可以将数据进行压缩,使其占用更少的存储空间,同时可以提高数据的传输效率。zlib可以与其他软件库配合使用,例如libcurl,以实现网络数据的传输和压缩。 openssl是一个开源的加密解密库。它提供了各种安全协议和算法的实现,包括SSL/TLS协议、RSA、AES等,用于保护网络通信的安全性。openssl被广泛应用于网络安全领域,用于实现加密通信、数字证书的生成和管理等功能。 在使用方面,VS主要用于开发和编译程序,可以方便地创建和管理项目,提供了丰富的开发工具和调试功能。而libcurl、zlib和openssl是用于程序开发过程中的库文件,可以被程序调用以实现特定功能。在网络应用开发中,常常需要使用libcurl来进行网络传输,同时可以结合zlib进行数据的压缩和解压缩,而openssl可以提供数据的安全加密和解密功能。 总之,VS是一个开发环境,而libcurl、zlib和openssl是开发中常用的软件库,它们在不同领域发挥着重要的作用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值