8.24 linux c socket 简单实现

程序是网上找的,注释很多都是看懂书后加上的  只是很简单的程序
其中的一个结构体可以查找资料

其中server端 :
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main()
{
     int sfp, nfp; /*定义两个描述符*/
     struct sockaddr_in s_add, c_add;
     int sin_size;
     unsigned short portnum = 0x8888;//服务使用端口
     
     printf("Hello,welcome to my server !\r\n");
     sfp = socket(AF_INET, SOCK_STREAM, 0);//创建套接字连接
     if(-1 == sfp){
         printf("socket fail! \n");
         return -1;
     }
     printf("socket is ok! \n");
     //填充服务器端口地址信息,以便下面使用此地址和端口监听
     bzero(&s_add,sizeof(struct sockaddr_in));/*  extern void bzero(void *s, int n);
             置字节字符串s的前n个字节为零且包括‘\0’。*/
     s_add.sin_family=AF_INET;//AF_INET   IPv4互联网协议
     s_add.sin_addr.s_addr = htonl(INADDR_ANY);//自动填出IP地址
     s_add.sin_port = htons(portnum);//端口号
/*使用bind进行绑定端口  函数:int bind(int sockfd, const struct sockaddr *addr,socklen_len len)
 *   指明函数套接字将使用本地的哪一个协议端口进行数据传送(IP地址和端口号),协议地址addr是通用地址,len是
 *  该地址结构(第二个参数)的长度。一般而言,服务器调用此函数,而客户端则很少调用它
 */
     if(-1 == bind(sfp,(struct sockaddr *)(&s_add),sizeof(struct sockaddr))){
         printf("bind fail !\r\n");
        return -1;
      }
     printf("bind ok ! \n");
     
/*int listen(int sockfd, int backlog)
 *作用:将为连接的套接字转换成被动套接字,提示内核应该接受指向此套接字的连接请求;第二个参数规定了内核为此套接
 *字排队的最大连接个数
 */     
     if(-1 == listen(sfp, 5)){
         printf("listen is fail !\n ");
        return -1;
      }
    printf("listen ok \n" );
    while (1){
        sin_size = sizeof(struct sockaddr_in);
/* accept服务端使用函数,调用时即进入阻塞状态,等待用户进行连接,在没有客户端进行连接时,程序停止在此处,
   不会看到后面的打印,当有客户端进行连接时,程序马上执行一次,然后再次循环到此处继续等待。
   此处accept的第二个参数用于获取客户端的端口和地址信息。
   int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
    */
        nfp = accept(sfp, (struct sockaddr *)(&c_add),&sin_size);
        if(-1 == nfp){
            printf("accept fail ! \n ");
            return -1;
        }
        printf("accept ok! \r\n Server start get connect from %#x : %#x\r\n",ntohl(c_add.sin_addr.s_addr),ntohs(c_add.sin_port) );
        //ntohl()是将一个无符号长整形数从网络字节顺序转换为主机字节顺序。
        //这里使用write向客户端发送信息
        if(-1 == write(nfp,"hello,welcome to my server \r\n",32)){
            printf("write fail ! \r\n");
            return -1;
        }
        printf("write ok \r\n");
        close(nfp);
    }
    return 0;
}

client端:
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
 
int main(void)
{
    int cfp;  //文件描述符
    int recbytes;
    int sin_size;
    char buffer[1024] = {0};
    struct sockaddr_in s_add, c_add;
    unsigned short portnum = 0x8888;
     
    printf("Hello,welcome to client !\r\n ");
    //建立socket 使用因特网,tcp流传输
    cfp  = socket(AF_INET, SOCK_STREAM, 0);
    if(-1  == cfp){
        printf("socket fail !\r\n");
        return -1;
    }
    printf("socket ok !\r\n");
    //构建服务器端的ip和端口信息,具体结构可以查资料
    bzero(&s_add,sizeof(struct sockaddr_in));
    s_add.sin_family = AF_INET;
    s_add.sin_addr.s_addr =inet_addr("192.168.1.106");  //ip地址根据自己情况而定
    s_add.sin_port = htons(portnum);/* 这里htons是将short型数据字节序由主机型转换为网络型,其实就是 
    将2字节数据的前后两个字节倒换,和对应的ntohs效果、实质相同,只不过名字不同。htonl和ntohl是 
    操作的4字节整形。将0x12345678变为0x78563412,名字不同,内容两两相同,一般情况下网络为大端, 
    PPC的cpu为大端,x86的cpu为小端,arm的可以配置大小端,需要保证接收时字节序正确。 
 */
    printf("s_add = %#x,port :%#x\r\n",s_add.sin_addr.s_addr, s_add.sin_port);
/*  int connet(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
 *
 */
    if(-1 == connect(cfp,(struct sockaddr *)(&s_add), sizeof(struct sockaddr))){
        printf("connect fail !\r\n");
        return -1;
    }
    printf("connect ok !\r\n");
    //链接成功, 从服务器端接收字符
    if(-1 == (recbytes = read(cfp,buffer,1024))){
        printf("read data fail !\r\n");
        return -1;
    }
    printf("read ok \r\nREC: \r\n");
    buffer[recbytes] = '\0';
    printf("%s\r\n", buffer);
     
    getchar();//此句为使程序暂停在此处,可以使用netstat查看当前的链接
    close(cfp);
    return 0;
}
运行结果:
server:

client:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值