/*socket->bind->listen->accept->recv/recvfrom->send/sendto->close

   客户端:socket->connect->send/sendto->recv/recvfrom->close

   其中服务器端首先建立起socket,然后调用本地端口的绑定,接着就开始与客服端建立联系,并接收客户端发送的消息。
客户端则在建立socket之后调用connect函数来建立连接。 服务器端的源代码如下所示:*/ /*"server.c"*/ #include<sys/types.h>
#include<sys/socket.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h> #define PORT 3490 //端口 #define BUFFER_SIZE 1024 //缓冲区大小 #define MAX_QUE_CONN_NM 5 //服务器等待连接队列的最大长度。 int main(){ struct sockaddr_in server_sockaddr,client_sockaddr; //分别定义服务器和客户端套接字
int sin_size,recvbytes;
int server_fd,client_fd;
char buf[BUFFER_SIZE]; //缓冲区 /*
SOCKET PASCAL FAR socket( int af, int type, int protocol);
af:一个地址描述。目前仅支持AF_INET格式,也就是说ARPA Internet地址格式。
type:指定socket类型。新套接口的类型描述类型,如TCP(SOCK_STREAM)和UDP(SOCK_DGRAM)。
常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等。
protocol:顾名思义,就是指定协议。套接口所用的协议。如调用者不想指定,可用0。
常用的协议有,IPPROTO_TCP、IPPROTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,
它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
*/
if((server_fd = socket(AF_INET,SOCK_STREAM,))== -){ //建立socket连接www.linuxidc.com
perror("create socket fail");
exit();
} printf("Socket id=%d\n",server_fd); /*设置sockaddr_in结构体中的相关参数*/ server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT); //由于在写网络程序时字节的网络顺序和主机顺序会有问题
server_sockaddr.sin_addr.s_addr = INADDR_ANY; //即0.0.0.0 任意地址
bzero(&(server_sockaddr.sin_zero),);
int i = ; //允许重复使用本地地址与套接字进行绑定 /*int PASCAL FAR setsockopt(SOCKET s,int level,int optname,const char FAR *optval,int optlen);
s:标识一个套接字的描述符。
level:选项定义的层次;目前仅支持SOL_SOCKET和IPPROTO_TCP层次。
optname:需设置的选项。
optval:指针,指向存放选项值的缓冲区。
optlen:optval缓冲区长度。
*/
setsockopt(server_fd,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i)); /*
int bind(SOCKET socket, const struct sockaddr *address,
socklen_t address_len);
参数说明:
socket:是一个套接字。
address:是一个sockaddr结构指针,该结构中包含了要结合的地址和端口号。
address_len:确定address缓冲区的长度。
返回值:如果函数执行成功,返回值为0,否则为SOCKET_ERROR。
*/
if(bind(server_fd,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr)) == -){ //绑定函数bind
perror("bind fail");
exit();
} printf("Bind success!\n"); /*
int PASCAL FAR listen( SOCKET s, int backlog);
S:用于标识一个已捆绑未连接套接口的描述字。
backlog:等待连接队列的最大长度。
*/
if(listen(server_fd,MAX_QUE_CONN_NM)== -){ //调用listen函数,创建为处理请求的队列
perror("listen fail");
exit();
} printf("Listening......\n"); /*
SOCKET PASCAL FAR accept( SOCKET s, struct sockaddr FAR* addr,int FAR* addrlen);
s:套接口描述字,该套接口在listen()后监听连接。
addr:(可选)指针,指向一缓冲区,其中接收为通讯层所知的连接实体的地址。Addr参数的实际格式由套接口创建时所产生的地址族确定。
addrlen:(可选)指针,输入参数,配合addr一起使用,指向存有addr地址长度的整型数。
*/
if((client_fd = accept(server_fd,(struct sockaddr *)&client_sockaddr,&sin_size))==-){//调用accept函数,等待客户端的接
perror("accept fail");
exit();
} printf("server: got connection from %s \n",inet_ntoa(client_sockaddr.sin_addr)); memset(buf,,sizeof(buf));
/*
int PASCAL FAR recv( SOCKET s, char FAR* buf, int len, int flags);
s:一个标识已连接套接口的描述字。
buf:用于接收数据的缓冲区。
len:缓冲区长度。
flags:指定调用方式。通常写成0
*/
if((recvbytes = recv(client_fd,buf,BUFFER_SIZE,)) == -){//调用recv函数接收客户端的请求
perror("recv fail");
exit();
} printf("Received a message: %s\n",buf); /*向客户起写数据*/
if(write(client_fd,"客户端我收到你发来的数据了,你能收到这句应答吗?\n",)==-)
perror("write error!"); close(client_fd); close(server_fd);
exit();
} /*客户端*/
/*client.c 运行方式:./client localhost*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define PORT 3490
#define MAXDATASIZE 5000
int main(int argc,char **argv)
{
int sockfd,nbytes;
char buf[];
struct hostent *he;
struct sockaddr_in srvaddr;
if(argc!=)
{
perror("Usage:client hostname\n");
exit();
}
/*函数gethostbyname获得指定域名地址所对应的ip地址*/
if((he=gethostbyname(argv[]))==NULL)
{
perror("gethostbyname");
exit();
}
/*创建套接字,返回套接字描述符*/
if((sockfd=socket(AF_INET,SOCK_STREAM,))==-)
{
perror("create socket error");
exit();
}
bzero(&srvaddr,sizeof(srvaddr));
/*用获得的远程服务器进程的ip地址和端口号来填充一个internet套接字地址结构*/
srvaddr.sin_family=AF_INET;
srvaddr.sin_port=htons(PORT);
srvaddr.sin_addr=*((struct in_addr *)he->h_addr);
/*用connect于这个远程服务器建立一个internet连接*/
if(connect(sockfd,(struct sockaddr *)&srvaddr,sizeof(struct sockaddr))==-)
{
perror("connect error");
exit();
} if((send(sockfd,"客户端向服务端发送数据,服务端你收到了吗?",,)) == -)
{
perror("send error");
exit();
} /*调用read函数读取服务器write过来的信息*/
if((nbytes=read(sockfd,buf,MAXDATASIZE))==-)
{
perror("read error");
exit();
}
buf[nbytes]='\0';
printf("read: %s",buf);
close(sockfd);
}

运行方式: gcc -o service service.c

      gcc -o client client.c

     chmod +x service

      chmod +x client

在一个终端运行:./service

在另一个终端运行:./client localhost

服务端输出:

Socket id=3 Bind success! Listening...... server: got connection from 127.0.0.1 Received a message: 客户端向服务端发送数据,服务端你收到了吗?

客户端输出:

read: 客户端我收到你发来的数据了,你能收到这句应答吗?

Linux 网络编程实例的更多相关文章

  1. Linux网络编程实例解析

    **************************************************************************************************** ...

  2. Linux网络编程——原始套接字实例:MAC 头部报文分析

    通过<Linux网络编程——原始套接字编程>得知,我们可以通过原始套接字以及 recvfrom( ) 可以获取链路层的数据包,那我们接收的链路层数据包到底长什么样的呢? 链路层封包格式 M ...

  3. linux网络编程_1

    本文属于转载,稍有改动,以利于学习. (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个 ...

  4. Linux网络编程入门 (转载)

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  5. [转] - Linux网络编程 -- 网络知识介绍

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  6. 【转】Linux网络编程入门

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  7. 《转》Linux网络编程入门

    原地址:http://www.cnblogs.com/duzouzhe/archive/2009/06/19/1506699.html (一)Linux网络编程--网络知识介绍 Linux网络编程-- ...

  8. Linux网络编程(三)

    Linux网络编程(三) wait()还是waitpid() Linux网络编程(二)存在客户端断开连接后,服务器端存在大量僵尸进程.这是由于服务器子进程终止后,发送SIGCHLD信号给父进程,而父进 ...

  9. linux网络编程基础--(转自网络)

    转自 http://www.cnblogs.com/MyLove-Summer/p/5215287.html Linux下的网络编程指的是socket套接字编程,入门比较简单. 1. socket套接 ...

随机推荐

  1. SpringBoot之使用jpa/hibernate

    Springboot版本是2.1.3.RELEASE 1.依赖 List-1.1 <dependency> <groupId>org.springframework.boot& ...

  2. 洛谷 P1446 [HNOI2008]Cards 解题报告

    P1446 [HNOI2008]Cards 题目描述 小春现在很清闲,面对书桌上的\(N\)张牌,他决定给每张染色,目前小春只有\(3\)种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun ...

  3. Moonraker:1靶机入侵

      0x01 前言 攻击Moonraker系统并且找出存在最大的威胁漏洞,通过最大威胁漏洞攻击目标靶机系统并进行提权获取系统中root目录下的flag信息. Moonraker: 1镜像下载地址: h ...

  4. Mysql基本的一些查询操作

    /*查询选修课程‘3-105’且成绩在60到80之间的所有记录.*/SELECT * FROM result WHERE CNO='3-105' AND GRADE > 60 AND GRADE ...

  5. Python之旅:集合

    Python数据类型 #作用:去重,关系运算, #定义: 知识点回顾 可变类型是不可hash类型 不可变类型是可hash类型 #定义集合: 集合:可以包含多个元素,用逗号分割, 集合的元素遵循三个原则 ...

  6. C++模版详解(-)

    C++模版:       模版时C++支持多参数多态的工具,使用模版可以为用户为类或函数声明一般模式,使得类的数据成员,或者成员函数的参数,返回值取得任意类型. 模版是一种对类型进行参数化的工具: 通 ...

  7. 使用 xhprof 进行 php 的性能分析

    基于本机环境(php7,macos) 1.xhprof 扩展 php7 下安装 xhprof 扩展: git clone https://github.com/longxinH/xhprof cd x ...

  8. 实验四:终极改造之使用EF

    回顾一下我们前面经过改造后的程序代码: (1)Listing.aspx:负责将Product对象集合(产品集合)按要求显示出来 (2)Repository.cs:负责读将数据库中读到的数据转换成Pro ...

  9. qq接入

    「花与剑: https://blog.csdn.net/wbbott/article/details/53107009」—————————

  10. kubernetes node管理

    目录 Node的扩缩容 删除node节点 Node的隔离与恢复 通过配置文件实现 通过命令行的方式实现 恢复 更新资源对象的label 给一个node添加一个label 将pod调度到指定的node ...