/*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. 51nod乘积之和

    题目链接 戳我 题意简述 你有长为\(n\)的序列和\(Q\)个询问,每次询问一个\(k\),求用\(k\)个数组成的不同方案的乘积的和. sol 显然要预处理一波. 考虑分治,左右两边都求出来后,怎 ...

  2. BZOJ3835 [Poi2014]Supercomputer 【斜率优化】

    题目链接 BZOJ3835 题解 对于\(k\),设\(s[i]\)为深度大于\(i\)的点数 \[ans = max\{i + \lceil \frac{s[i]}{k}\} \rceil\] 最优 ...

  3. Moonraker:1靶机入侵

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

  4. Java考试题之九

    QUESTION 177 Given: 1.     class TestException extends Exception { } 2.     class A { 3.     public ...

  5. bzoj3839【Pa2013】Działka

    题目描述 平面上有n个不重复的点.每次询问一个边平行坐标轴的矩形内(包含边界)的点组成的凸包的面积.. 输入格式 第一行两个整数k,n(1<=k<=1000000,3<=n<= ...

  6. 【bzoj3832】Rally

    Portal -->bzoj3832 Description ​ 给你一个DAG,每条边长度都是\(1\),请找一个点满足删掉这个点之后剩余图中的最长路最短 Solution ​​ 这题的话感觉 ...

  7. Python完成RF测试用例

    Robot Framework 框架是基于 Python 语言开发的,所以,它本质上是 Python 的一个库. from robot.api import TestSuite from robot. ...

  8. BRIEF特征点描述子

    简介 BRIEF是2010年的一篇名为<BRIEF:Binary Robust Independent Elementary Features>的文章中提出,BRIEF是对已检测到的特征点 ...

  9. Leetcode 503. 下一个更大元素 II

    1.题目描述 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应 ...

  10. CentOS7.3 部署Haproxy 1.7.2

    haproxy:http://www.haproxy.org/ 本文涉及haproxy的安装,并做简单配置. 一.环境准备 1. 操作系统 CentOS-7-x86_64-Everything-151 ...