Linux 网络编程三(socket代码详解)

//网络编程客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>//htons()函数头文件
#include <netinet/in.h>//inet_addr()头文件

int main(int arg,char *args[])
{
    int st=socket(AF_INET,SOCK_STREAM,0);//初始化socket
    if(st==-1)
    {
        printf("init socket failed ! error message :%s\n",strerror(errno));
        return -1;
    }
    struct sockaddr_in addr;//定义IP地址结构
    memset(&addr,0,sizeof(addr));
    addr.sin_family=AF_INET;//设置结构地址类型为TCP/IP地址
    /*
     字节转化
            网络当中传输数据是以字节为单位,short类型无法在网络中传输,必须转化成网络类型,
            例如short类型有2个字节,在网络传输中无法知道哪个是高位字节,那个是低位字节,所以系统提供htons()函数来处理。
            所以,在网络中传输非char型数据,必须调用相应的系统函数,将这个类型转化成网络中的char类型。
     */
    addr.sin_port=htons(8080);//指定端口号  htons:将short类型从host字节类型到net字节类型转化
    /*
     IP地址在内存中是一个整数,但是我们习惯于写一个字符串
     inet_addr()函数能将一个字符串的IP地址转化成一个int类型数字
     但是inet_addr()在多线程中有问题,我们一般使用自定义类型那个
     */
    addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    //调用connect()函数连接结构addr指定的IP地址和端口号
    /*
      connect()函数第二个参数详解:
      struct sockaddr类型是一个比较旧的类型,现在一般都使用struct sockaddr_in类型
          但是struct sockaddr和struct sockaddr_in类型是相互兼容的
     */
    if(connect(st,(struct sockaddr *)&addr,sizeof(addr))==-1)
    {
        printf("connect failed ! error message :%s\n",strerror(errno));
        goto END;
    }
    char buf[1024]={0};
    strcpy(buf,"fly on air !\n");
    if(send(st,buf,strlen(buf),0)==-1)//发送buf中的数据
    {
        printf("send failed ! error message:%s\n",strerror(errno));
        goto END;
    }
END:
    close(st);
    return 0;
}
//网络编程服务端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>//htons()函数头文件
#include <netinet/in.h>//inet_addr()头文件

int main(int arg,char *args[])
{
    int st=socket(AF_INET,SOCK_STREAM,0);//初始化socket
    if(st==-1)
    {
        printf("init socket failed ! error message :%s\n",strerror(errno));
        return -1;
    }

    int on=1;
    if(setsockopt(st,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))==-1)
    {
        printf("setsockopt failed ! error message :%s\n",strerror(errno));
        goto END;
    }

    struct sockaddr_in addr;
    memset(&addr,0,sizeof(addr));
    addr.sin_family=AF_INET;
    //服务端绑定端口号时,需要去系统设置里将该端口号打开
    addr.sin_port=htons(8080);
    /*
     htonl()函数将一个4字节的long类型数据转化成网络类型
     */
    addr.sin_addr.s_addr=htonl(INADDR_ANY);//INADDR_ANY代表这个server上所有的地址
    //将IP地址与server进行绑定
    if(bind(st,(struct sockaddr *)&addr,sizeof(addr))==-1)
    {
        printf("bind IP addr failed ! error message:%s\n",strerror(errno));
        goto END;
    }
    //server开始listen
    if(listen(st,10)==-1)
    {
        printf("listen failed ! error message :%s\n",strerror(errno));
        goto END;
    }
    int client_st=0;//client端socket
    struct sockaddr_in clientaddr;//client端的IP地址
    char buf[1024]={0};
    int i=0;
    while(i<1)
    {
        memset(&clientaddr,0,sizeof(clientaddr));
        socklen_t len=0;//表示client地址的最大字节数
        /*
         accept会阻塞当前线程,直到有客户端连接过来,accept()函数返回client端的socket描述符
         */
        client_st=accept(st,(struct sockaddr *)&clientaddr,&len);
        if(client_st==-1)
        {
            printf("accept failed ! error message :%s\n",strerror(errno));
            goto END;
        }
        if(recv(client_st,buf,sizeof(buf),0)==-1)//接收来自client端的消息
        {
            printf("recv failed , send from IP  error message:%s\n",strerror(errno));
            close(client_st);//关闭client端socket
            goto END;
        }
        printf("%s",buf);
        close(client_st);//关闭client端socket
        memset(buf,0,sizeof(buf));
        i++;
    }
END:
    close(st);//关闭服务器socket
    return 0;
}
.SUFFIXES:.c .o
CC=gcc
SRCS1=myclient.c
SRCS2=server.c
OBJS1=$(SRCS1:.c=.o)
OBJS2=$(SRCS2:.c=.o)
EXEC1=mclient
EXEC2=mserver

start:$(OBJS1) $(OBJS2)
    $(CC) -o $(EXEC1) $(OBJS1)
    $(CC) -o $(EXEC2) $(OBJS2)
    @echo "-------ok-----------"
.c.o:
    $(CC) -Wall -g -o [email protected] -c $<
clean:
    rm -f $(OBJS1)
    rm -f $(EXEC1)
    rm -f $(OBJS2)
    rm -f $(EXEC2)
时间: 2024-10-13 11:39:38

Linux 网络编程三(socket代码详解)的相关文章

linux网络编程-(socket套接字编程UDP传输)

今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中,如果我们使用TCP传输,会造成传输速度较慢的情况,所以我们在进行文件传输的过程中,最好要使用UDP传输. 在其中,我们需要写两个程序,一个客户端,一个服务端,在一个终端中,先运行服务端,在运行客户端,在服务端和客户端都输入IP地址和端口号,注意服务端和客户端的端口号要相同,然后选择功能,在linux

Linux网络编程基础-socket

一.协议的概念 1. 什么是协议 从应用的角度出发,协议可理解为“规则”,是数据传输和数据的解释的规则. 假设,A.B双方欲传输文件.规定: 第一次,传输文件名,接收方接收到文件名,应答OK给传输方: 第二次,发送文件的尺寸,接收方接收到该数据再次应答一个OK: 第三次,传输文件内容.同样,接收方接收数据完成后应答OK表示文件内容接收成功. 由此,无论A.B之间传递何种文件,都是通过三次数据传输来完成.A.B之间形成了一个最简单的数据传输规则.双方都按此规则发送.接收数据.A.B之间达成的这个相

linux-socket tcp客户端服务器编程模型及代码详解

上一篇文章介绍了 TCP/IP相关协议,socket通信流程和涉及到的各种函数: Socket简单理解 本篇将具体解释tcp客户端服务器编程模型相关的代码 文章分为4个部分: 1. TCP客户端服务器编程模型流程图 2. 网络字节序与主机字节序 3. TCP编程的地址结构 4. 详细案例代码及解释 一: TCP客户端服务器编程模型流程图 上面两张图片将整个流程已经说明的很清楚了; 二: 网络字节序与主机字节序 字节序即是保存数据的方向方式, 分为 大端存储 和 小端存储; 其中 网络字节序 使用

iOS开发——网络编程Swift篇&amp;Alamofire详解

Alamofire详解 预览图 Swift Alamofire 简介 Alamofire是 Swift 语言的 HTTP 网络开发工具包,相当于Swift实现AFNetworking版本. 当然,AFNetworking非常稳定,在Mac OSX与iOS中也能像其他Objective-C代码一样用Swift编写.不过Alamofire更适合Swift语言风格习惯(Alamofire与AFNetworking可以共存一个项目中,互不影响). Alamofire 取名来源于Alamo Fire fl

Linux 网络编程(socket多线程升级版)

//网络编程--客户端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <pthread.h> #include <netinet/in.h>

Linux网络编程3&mdash;&mdash;socket

宏定义 首先介绍两个宏定义,看如下代码 代码1 /************************************************************************* > File Name: test.c > Author: KrisChou > Mail:[email protected] > Created Time: Thu 28 Aug 2014 10:11:59 AM CST ********************************

Linux网络编程三、 IO操作

当从一个文件描述符进行读写操作时,accept.read.write这些函数会阻塞I/O.在这种会阻塞I/O的操作好处是不会占用cpu宝贵的时间片,但是如果需要对多个描述符操作时,阻塞会使同一时刻只能处理一个操作,从而使程序的执行效率大大降低.一种解决办法是使用多线程或多进程操作,但是这浪费大量的资源.另一种解决办法是采用非阻塞.忙轮询,这种办法提高了程序的执行效率,缺点是需要占用更多的cpu和系统资源.所以,最终的解决办法是采用IO多路转接技术. IO多路转接是先构造一个关于文件描述符的列表,

网络编程三 Socket

1.根据netstat端口的找到进程号---->根据进程号找到进程名称-------->终止进程 1) netstat    最后一列是5432 C:\Users\Administrator> netstat -ano|findstr 8848 TCP 127.0.0.1:8848 0.0.0.0:0 LISTENING 5432 2) tasklist核实进程名称以及内存占用情况 C:\Users\Administrator>tasklist /fi "PID eq 5

嵌入式 Linux网络编程(一)——Socket网络编程基础

嵌入式 Linux网络编程一--Socket网络编程基础 一.Socket简介 1.网络中进程间通信 本机进程使用进程号区别不同的进程进程间通信方式有管道.信号.消息队列.共享内存.信号量等.网络中进程间的通信首先需要识别进程所在主机在网络中的唯一标识即网络层的IP地址主机上的进程可以通过传输层的协议与端口号识别. 2.Socket原理 Socket是应用层与TCP/IP协议族通信的中间软件抽象层是一种编程接口.Socket屏蔽了不同网络协议的差异支持面向连接(Transmission Cont