一个关于linux socket的简单例子

本文介绍了一个简单的客户端-服务器文件传输程序实现,通过C语言完成文件的发送与接收。客户端指定服务器IP地址及文件名,服务器查找文件并发送给客户端。

客户端:dl_client.c
#include "unp.h"

int main(int argc,char *argv[])
{
    char recvbuff[50],buff[50],*p;
    int sockfd,len,ret,test;
    struct sockaddr_in serveraddr;
    FILE *fp;
   
    if(argc != 3){
        printf("input:./client <IPaddress> <filename>/n");
        return 0;
    }
   
    if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0){
        printf("socket error/n");
        return 0;
    }
       
    bzero(&serveraddr,sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(SERV_PORT);
    if(inet_pton(AF_INET,argv[1],&serveraddr.sin_addr) <= 0){
        printf("inet_pton error for %s/n",argv[1]);
        return 0;
    }
   
    if(connect(sockfd,(SA *)&serveraddr,sizeof(serveraddr)) < 0){
        printf("connect error1/n");
        return 0;
    }
   
    bzero(buff,sizeof(buff));
    strcpy(buff,argv[2]);
    send(sockfd,buff,sizeof(buff), 0);
    bzero(buff,sizeof(buff));
    sprintf(buff,"./dl_%s",argv[2]);
    recv(sockfd,recvbuff,sizeof(recvbuff),0);
    len = 0;
    ret = 0;
    if((len = atoi(recvbuff)) > 0){
        p = (char *)malloc(len + 1);
        bzero(p, len + 1);
        test = recv(sockfd,p,len,0);
        printf("***test = %d/n",test);
        printf("***len = %d/n",len);
        if((fp = fopen(buff,"w+")) != NULL){
            ret = fwrite(p,len,1,fp);
            fclose(fp);
        }
        free(p);
    }
    if(len != 0 && ret == 1)
        printf("Download %s OK!/n",argv[2]);
    else printf("Download error!/n");
   
    close(sockfd);
   
    return 0;
}
服务端:dl_server.c
#include "unp.h"

int Socket(int family,int type,int protocol)
{
    int ret;
    ret = socket(family,type,protocol);
    if(ret < 0){
        printf("socket error/n");
    }
    return ret;
}

void Bind(int sockfd,const struct sockaddr *myaddr,socklen_t addrlen)
{
    if(bind(sockfd,myaddr,addrlen) < 0)
        printf("bind error/n");
}

void Listen(int fd, int backlog)
{
    char *ptr;
    if((ptr = getenv("LISTENQ")) != NULL)
        backlog = atoi(ptr);
    if(listen(fd,backlog) < 0)
        printf("listen error/n");
}

int Fork()
{
    if(fork() == 0)
        return 0;
    else
        return -1;
}

int main(int argc,char *argv[])
{
    char recvbuff[50],path[50],*p = NULL;
    int listensock,connsock,ret,len;
    pid_t childpid;
    socklen_t clilen;
    struct sockaddr_in servaddr,cliaddr;
    FILE *fp;
   
    listensock = Socket(AF_INET,SOCK_STREAM,0);
   
    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERV_PORT);
   
    Bind(listensock,(SA *)&servaddr,sizeof(servaddr));
   
    Listen(listensock,LISTENQ);
   
    for( ; ; ){
        clilen = sizeof(cliaddr);
        connsock = accept(listensock,(SA *)&cliaddr,&clilen);
       
        if((childpid = Fork()) == 0){
            bzero(recvbuff,sizeof(recvbuff));
            bzero(path,sizeof(path));
            recv(connsock,recvbuff,sizeof(recvbuff),0);
            sprintf(path,"./%s",recvbuff);
           
            ret = -1;
            if((fp = fopen(path, "r")) != NULL){
                fseek(fp, 0, SEEK_END);
                len = ftell(fp);
                p = (char *)malloc(len + 1);
                bzero(p, len + 1);
                fseek(fp, 0, SEEK_SET);
                ret = fread(p,len + 1,1,fp);
                fclose(fp);
            }
            if(ret != -1){
                bzero(path,sizeof(path));
                sprintf(path,"%d",len);
                send(connsock,path,sizeof(path),0);
                send(connsock,p,len + 1,0);
            }
            else{
                len = 0;
                bzero(path,sizeof(path));
                sprintf(path,"%d",len);
                send(connsock,path,sizeof(path),0);
            }
            free(p);
           
            close(listensock);
            return 0;
        }
        close(connsock);
    }
}
包含的头文件:unp.h(从项目里拿出来的,可能有出入)
#include <getopt.h>
#include <resolv.h>
#include <dirent.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/un.h>

#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif

#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif

#ifdef HAVE_POLL_H
#include <poll.h>
#endif

#ifdef HAVE_SYS_EVENT_H
#include <sys/event.h>
#endif

#ifdef HAVE_STRINGS_H
#include <string.h>
#endif

#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif

#ifdef HAVE_SYS_FILIO_H
#include <sys/filio.h>
#endif

#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif

#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif

#ifdef HAVE_ENT_IF_DL_H
#include <net/if_dl.h>
#endif

#ifdef HAVE_NETINET_SCTP_H
#include <netinet/sctp.h>
#endif

#ifdef _osf_
#undef recv
#undef send
#define recv(a,b,c,d) recvfrom(a,b,c,d,0,0)
#define send(a,b,c,d) sendto(a,b,c,d,0,0)
#endif

#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif

#ifndef SHUT_RD
#define SHUT_RD 0
#define SHUT_WR 1
#define SHUT_RDWR 2
#endif

#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif

#ifndef INET6_ADDRSTRLEN
#define INET_ADDRSTRLEN 46
#endif

#ifndef HAVE_BZERO
#define bzero(ptr,n) memset(ptr,0,n)
#endif

#ifndef HAVE_GETHOSTBYNAME2
#define gethostbyname2(host,family) gethostbyname((host))
#endif

struct unp_in_pktinfo{
    struct in_addr ipi_addr;
    int ipi_ifindex;
};

#ifndef CMSG_LEN
#define CMSG_LEN(size)
#endif

#ifndef CMSG_SPACE
#define CMSG_SPACE(size)
#endif

#ifndef SUN_LEN
#define SUN_LEN(su) (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
#endif

#ifndef AF_LOCAL
#define AF_LOCAL AF_UNIX
#endif
#ifndef PF_LOCAL
#define PF_LOCAL PF_UNIX
#endif

#ifndef INFTIM
#define INFTIM (-1)
#ifdef HAVE_POLL_H
#define INFTIM_UNPH
#endif
#endif

#define LISTENQ 1024

#define MAXLINE 4096
#define BUFFSIZE 8192

#define SERV_PORT 9877
#define SERV_PORT_STR "9877"
#define UNIXSTR_PATH "/tmp/unix.str"
#define UNIXDG_PATH "/tmp/unix.dg"

#define SA     struct sockaddr

#define HAVE_STRUCT_SOCKADDR_STORAGE
#ifndef HAVE_STRUCT_SOCKADDR_STORAGE

#define _SS_MAXSIZE 128
#define _SS_ALIGNSIZE (sizeof(int64_t))
#ifdef HAVE_SOCKADDR_SA_LEN
#define _SS_PAD1SIZE (_SS_ALIGNSIZE -sizeof(u_char) -sizeof(sa_family_t))
#else
#define _SS_PAD1SIZE (_SS_ALIGNSIZE -sizeof(sa_family_t))
#endif
#define _SS_PAD2SIZE (_SS_MAXSIZE -2*_SS_ALIGNSIZE)

struct sockaddr_storage{
#ifdef HAVE_SOCKADDR_SA_LEN
    u_char ss_len;
#endif
    sa_family_t ss_family;
    char _ss_pad1[_SS_PAD1SIZE];
    int64_t _ss_align;
    char _ss_pad2[_SS_PAD2SIZE];
};
#endif

#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)

typedef void Sigfunc(int);

#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))

#ifndef HAVE_ADDRINFO_STRUCT
//#include "../lib/addrinfo.h"
#endif

#ifndef HAVE_IF_NAMEINDEX_STRUCT
struct if_nameindex{
    unsigned int if_index;
    char *if_name;
};
#endif

分别编译客户端和服务端,并运行。一个简单数据传输就OK了!


也是从csdn上看的!自己实践了一下!没问题!不过!要注意linux系统局域网的设置!

<think>我们正在寻找一个简单LinuxSocket通信示例。根据用户要求,我们将提供一个TCP协议的客户端和服务器端通信示例。我们将参考之前提供的epoll示例中的部分,但这里为了简单,先使用阻塞模式的基本socket函数。目标:客户端发送一条消息给服务器,服务器接收并打印,然后回复一个固定消息,客户端接收并打印回复。步骤:1.服务器端:-创建socket-绑定地址和端口-监听连接-接受客户端连接-接收客户端消息并打印-发送回复消息-关闭连接2.客户端:-创建socket-连接服务器-发送消息-接收回复并打印-关闭连接注意:为了简化,我们使用阻塞式I/O,且不处理多连接(一次只服务一个客户端)。参考之前的引用[2]中有一个客户端的代码片段,我们可以基于此完善。同时引用[1]提到select函数,但我们这里先不使用多路复用,只使用基本函数。下面我们将分别编写服务器和客户端的代码。</think> 下面是一个简单Linux Socket通信示例,包含服务端和客户端代码: ### 服务端代码 (server.c) ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 8888 #define BUFFER_SIZE 1024 int main() { int server_fd, client_fd; struct sockaddr_in address; socklen_t addr_len = sizeof(address); char buffer[BUFFER_SIZE] = {0}; // 1. 创建socket if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // 2. 配置服务器地址 address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // 3. 绑定socket到地址 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } // 4. 监听连接 if (listen(server_fd, 3) < 0) { perror("listen failed"); exit(EXIT_FAILURE); } printf("Server listening on port %d\n", PORT); // 5. 接受连接 if ((client_fd = accept(server_fd, (struct sockaddr *)&address, &addr_len)) < 0) { perror("accept failed"); exit(EXIT_FAILURE); } // 6. 读取客户端消息 int read_size = read(client_fd, buffer, BUFFER_SIZE); printf("Received %d bytes: %s\n", read_size, buffer); // 7. 发送响应 char *response = "Message received!"; write(client_fd, response, strlen(response)); printf("Response sent\n"); // 8. 关闭连接 close(client_fd); close(server_fd); return 0; } ``` ### 客户端代码 (client.c) ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define SERVER_IP "127.0.0.1" #define PORT 8888 #define BUFFER_SIZE 1024 int main() { int sock; struct sockaddr_in serv_addr; char buffer[BUFFER_SIZE] = {0}; // 1. 创建socket if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Socket creation error"); exit(EXIT_FAILURE); } // 2. 配置服务器地址 serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // 3. 转换IP地址 if (inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr) <= 0) { perror("Invalid address/Address not supported"); exit(EXIT_FAILURE); } // 4. 连接服务器 if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("Connection failed"); exit(EXIT_FAILURE); } printf("Connected to server\n"); // 5. 发送消息 char *message = "Hello from client!"; send(sock, message, strlen(message), 0); printf("Message sent\n"); // 6. 读取响应 int read_size = read(sock, buffer, BUFFER_SIZE); printf("Server response: %s\n", buffer); // 7. 关闭连接 close(sock); return 0; } ``` ### 编译与运行 ```bash # 编译服务端 gcc server.c -o server # 编译客户端 gcc client.c -o client # 先运行服务端 ./server # 在新终端运行客户端 ./client ``` ### 功能说明 1. **服务端**: - 创建Socket绑定到本地端口8888 - 监听并接受客户端连接 - 接收客户端消息并打印 - 发送响应消息 - TCP协议保证了可靠传输[^3] 2. **客户端**: - 连接本地服务端 - 发送字符串消息 - 接收并打印服务端响应 3. **数据传输流程**: $$ \text{客户端} \xrightarrow{\text{Hello from client!}} \text{服务端} \xrightarrow{\text{Message received!}} \text{客户端} $$ ### 执行结果 ``` # 服务端输出 Server listening on port 8888 Received 18 bytes: Hello from client! Response sent # 客户端输出 Connected to server Message sent Server response: Message received! ``` ### 关键概念 1. `socket()`: 创建通信端点[^1] 2. `bind()`: 绑定地址和端口 3. `listen()`: 设置监听队列大小 4. `accept()`: 接受传入连接 5. `connect()`: 客户端连接服务器 6. `read()/write()`: 数据传输函数[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值