/*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. 【UOJ#80】二分图最大权匹配(KM)

    题面 UOJ 题解 模板qaq #include<iostream> #include<cstdio> #include<cstdlib> #include< ...

  2. 【ARC083E】Bichrome Tree

    Description ​ 给一棵\(n\)个节点的树,和一个长度同样为\(n\)的非负整数序列\(x_i\). ​ 请尝试对每个节点染黑或白两种颜色,并确定一个非负整数权值. ​ 问是否存在一种方案 ...

  3. 主动分布式WEB资产扫描

      一. Redis的服务安装 系统环境:centos7x64   ip地址:192.168.1.11 1.设置静态IP地址 [root@localhost backlion]#vi /etc/sys ...

  4. POJ.1067 取石子游戏 (博弈论 威佐夫博弈)

    POJ.1067 取石子游戏 (博弈论 威佐夫博弈) 题意分析 简单的威佐夫博弈 博弈论快速入门 代码总览 #include <cstdio> #include <cmath> ...

  5. MySQL 第五篇:索引原理与慢查询优化

    一 介绍 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句 ...

  6. [poj 1533]最长上升子序列nlogn树状数组

    题目链接:http://poj.org/problem?id=2533 其实这个题的数据范围n^2都可以过,只是为了练习一下nlogn的写法. 最长上升子序列的nlogn写法有两种,一种是变形的dp, ...

  7. sidecar学习

    1.SideCar的出现 微服务的结构是细粒度的,由多个服务构成,支持不同的服务用不同的语言来编写,比如a服务用python,b服务用java,C服务用php等,我们称为异构语言,那么在利用zuul来 ...

  8. ACF/PACF,残差白噪声的检验问题

    关于自相关.偏自相关: 一.自协方差和自相关系数       p阶自回归AR(p)       自协方差 r(t,s)=E[X(t)-EX(t)][X(s)-EX(s)]       自相关系数ACF ...

  9. windows下用wubi快速安装ubuntu

    由于开发需要,我们可能要用到ubuntu,然而又不能完全抛弃windows,于是双系统是个不错选择. wubi是一个在windows下快速安装ubuntu双系统的工具,它包含在ubuntu 12及以前 ...

  10. Git之原有基础开发新功能

    场景描述 当一个项目已经上线,同时又在原有基础上新增功能模块,于是乎就要在原有代码的基础上进行开发,在新增模块功能的开发的过程中,项目发现了一个紧急Bug,需要修复.操作流程如下: