`
andrew913
  • 浏览: 188800 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

linux socket 学习笔记

阅读更多
1.创建套接字:socket()
/* Create a new socket of type TYPE in domain DOMAIN, using
   protocol PROTOCOL.  If PROTOCOL is zero, one is chosen automatically.
   Returns a file descriptor for the new socket, or -1 for errors.  */
extern int socket (int __domain, int __type, int __protocol) __THROW;

int __domain:UNIX系统支持的地址族有:AF_UNIX、AF_INET、AF_NS等,而DOS、WINDOWS中仅支持AF_INET,它是网际网区域,Linux环境下AF_INET就可以了。


int __type:是一种类型,这里可以采用SOCK_STREAM

int __protocol:参数protocol说明该套接字使用的特定协议,如果调用者不希望特别指定使用的协议,则置为0,使用默认的连接模式。
根据这三个参数建立一个套接字,并将相应的资源分配给它,同时返回一个整型套接字号。

2.指定本地地址──bind() 
/* Give the socket FD the local address ADDR (which is LEN bytes long).  */
extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)


当一个套接字用socket()创建后,存在一个名字空间(地址族),但它没有被命名。bind()将套接字地址(包括本地主机地址和本地端口地址)与所创建的套接字号联系起来,即将名字赋予套接字,以指定本地半相关。

eg:
bind(socket_descriptor,(struct socketaddr *)&sin, sizeof(sin) );


这里的sin 就是我们定义的struct sockaddr_in,
socket_descriptor就是上面socket()返回的那个套接字号。

返回:
成功:0
失败:SOCKET_ERROR,我们可以通过PERROR这个函数来打印失败原因。

3.建立套接字连接──connect()与accept()

/* Open a connection on socket FD to peer at ADDR (which LEN bytes long).
   For connectionless socket types, just set the default address to send to
   and the only address from which to accept transmissions.
   Return 0 on success, -1 for errors.  */
extern int connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)

/* Await a connection on socket FD.
   When a connection arrives, open a new socket to communicate with it,
   set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting
   peer and *ADDR_LEN to the address's actual length, and return the
   new socket's descriptor, or -1 for errors.  */
extern int accept (int __fd, __SOCKADDR_ARG __addr,
                   socklen_t *__restrict __addr_len)

这两个系统调用用于完成一个完整相关的建立,其中connect()用于建立连接。无连接的套接字进程也可以调用connect(),但这时在进程之间没有实际的报文交换,调用将从本地操作系统直接返回。这样做的优点是程序员不必为每一数据指定目的地址,而且如果收到的一个数据报,其目的端口未与任何套接字建立“连接”,而accept()用于使服务器等待来自某客户进程的实际连接。 

eg:
accept(socket_descriptor,(struct socketaddr *)&sin,sizeof(struct sockaddr_in));

connect(socket_descriptor, (void *)&pin, sizeof(pin))

socket_descriptor:就是上面获取的套接字号,sin是我们定义的struct sockaddr_in,最后一个参数就是这种结构体的大小。

四个套接字系统调用,socket()、bind()、connect()、accept(),可以完成一个完全五元相关的建立。socket()指定五元组中的协议元,它的用法与是否为客户或服务器、是否面向连接无关。bind()指定五元组中的本地二元,即本地主机地址和端口号,其用法与是否面向连接有关:在服务器方,无论是否面向连接,均要调用bind();若采用面向连接,则可以不调用bind(),而通过connect()自动完成。若采用无连接,客户方必须使用bind()以获得一个唯一的地址。

4.监听连接──listen() 
此调用用于面向连接服务器,表明它愿意接收连接。listen()需在accept()之前调用,其调用格式如下: 

int PASCAL FAR listen(SOCKET s, int backlog); 

参数s标识一个本地已建立、尚未连接的套接字号,服务器愿意从它上面接收请求。backlog表示请求连接队列的最大长度,用于限制排队请求的个数,目前允许的最大值为5。如果没有错误发生,listen()返回0。否则它返回SOCKET_ERROR。 

listen()在执行调用过程中可为没有调用过bind()的套接字s完成所必须的连接,并建立长度为backlog的请求连接队列。 

调用listen()是服务器接收一个连接请求的四个步骤中的第三步。它在调用socket()分配一个流套接字,且调用bind()给s赋于一个名字之后调用,而且一定要在accept()之前调用。 

5 数据传输──send()与recv() 

当一个连接建立以后,就可以传输数据了。常用的系统调用有send()和recv()。 

send()调用用于套接字标识符s指定的已连接的数据报或流套接字上发送输出数据,格式如下: 

int PASCAL FAR send(SOCKET s, const char FAR *buf, int len, int flags); 

参数s为已连接的本地套接字描述符。buf 指向存有发送数据的缓冲区的指针,其长度由len 指定。flags 指定传输控制方式,如是否发送带外数据等。如果没有错误发生,send()返回总共发送的字节数。否则它返回SOCKET_ERROR。
recv()调用用于套接字标识符指定的已连接的数据报或流套接字上接收输入数据,格式如下: 

int PASCAL FAR recv(SOCKET s, char FAR *buf, int len, int flags); 

参数s 为已连接的套接字描述符。buf指向接收输入数据缓冲区的指针,其长度由len 指定。flags 指定传输控制方式,如是否接收带外数据等。如果没有错误发生,recv()返回总共接收的字节数。如果连接被关闭,返回0。否则它返回SOCKET_ERROR。
下面以一个简单的实例来记录我的学习

server.c
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
	int socket_descriptor;
	socket_descriptor = socket(AF_INET, SOCK_STREAM, 0);

	int port = 8000;
	struct sockaddr_in sin;
	int temp_socket_descriptor;
	int rval=1;
	char buf[1024];
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = htonl(INADDR_ANY);
	sin.sin_port = htons(port);
	bind(socket_descriptor,(struct socketaddr *)&sin, sizeof(sin) );
	listen(socket_descriptor, 128);
	
	if(fork()==0)
	{
		while(1) 
		{
			int len=sizeof(sin);

			temp_socket_descriptor = accept(socket_descriptor,(struct socketaddr *)&sin,
															 &len);
			if (temp_socket_descriptor<0)
			{
				perror("accept");
				exit(0);
			}
			while (rval)
			{
				memset(buf, 0, sizeof(buf)); 
				rval=recv(temp_socket_descriptor,buf,1024,0);
				if(rval<0)
				{
					perror("recv");
					exit(1);
				}
				else if(rval==0)
				{	
					printf("end receiving\n");
				}
				else if(memcmp(buf,"add",3)==0)
				{
					printf("add the function\n");
				}
				else
				{
					printf("delete the function\n");
				}
			}
			rval=1;
			close(temp_socket_descriptor);
		}
	}
	else
	{
		int i=0;
		for(i=0;i<100;i++)
		{
			sleep(1);
			printf("i am the parent \n");
		}
		wait(NULL);
	}
return 0;
}


client.c
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 
#include <stdio.h>
int main(int argc,char *args[])
{
	char  host_name[1024] ="172.18.4.200";
	struct hostent * server_host_name;
	server_host_name = gethostbyname(host_name);
	int socket_descriptor;
	
	int port = 8000;
	struct sockaddr_in pin;
	if(argc!=2)
	{
		printf("the number is error\n");
		return 1;
	}
	else 
	{
		printf("%s\n",args[1]);
	}
	pin.sin_family = AF_INET;
	pin.sin_addr.s_addr = inet_addr("127.0.0.1");
	pin.sin_port = htons(port);
	bzero(&(pin.sin_zero), 8);
	
	socket_descriptor = socket(AF_INET, SOCK_STREAM, 0);
	if(connect(socket_descriptor, (void *)&pin, sizeof(pin))==-1)
	{
		perror("connect");
		exit(1);
	}
	if (send(socket_descriptor,args[1],strlen(args[1]),0)<0)
	{
		perror("send");
		exit(2);
	}
	close(socket_descriptor); 
	return 0;
}



分享到:
评论

相关推荐

    linux socket编程笔记.rar

    Linux Socket编程是Linux系统中进行网络通信的核心技术,它为应用程序提供了一种接口,...通过对这些笔记的学习,开发者可以掌握Linux环境下进行网络编程的基本技能,从而开发出能够进行高效、稳定网络通信的应用程序。

    linux编程学习笔记PDF资料下载.txt

    根据提供的文件信息,我们可以推断出这是一份关于Linux编程学习笔记的PDF资料。下面将对这份资料可能涉及的关键知识点进行详细的阐述。 ### Linux编程基础知识 #### 1. Linux操作系统概述 - **定义与特点**:Linux...

    linux嵌入式Socket网络编程学习笔记

    Linux 嵌入式Socket网络编程是开发物联网设备、服务器通信等领域的核心技术。Socket编程允许程序通过网络发送和接收数据,是实现网络通信的基础。在Linux环境下,Socket接口被广泛用于嵌入式设备的网络功能实现,...

    linux运维学习笔记:MySQL多实例配置实战.pdf

    MySQL多实例配置,顾名思义,是指在单台服务器上运行多个MySQL实例。每个实例能够监听不同的端口,拥有独立的配置文件、数据文件和启动...掌握如何合理配置和管理MySQL多实例,对于Linux运维工程师来说是一项必备技能。

    Linux 0.11学习笔记

    本篇笔记将围绕Linux 0.11的核心特性、内核结构、编译安装以及相关命令行操作进行详细介绍。 1. **Linux 0.11核心特性**: - Linux 0.11是一个单用户、多任务的操作系统,支持抢占式调度,允许多个程序同时运行。 ...

    socket学习笔记

    在本文中,我们将深入探讨"socket学习笔记"中的关键概念和技术细节。 首先,让我们理解什么是Socket。Socket是应用层与传输层之间的一个接口(API),它允许程序通过网络进行数据交换。在TCP/IP协议族中,Socket...

    linux下C语言开发笔记整理

    Linux下C语言开发笔记整理涵盖了从基础知识到网络通信的多个方面,主要围绕在Unix/Linux系统环境下使用C语言进行软件开发的各项技术与理论。以下是从文件提供的信息中提炼的知识点。 ### Unix/Linux系统基本命令和...

    Linux+Kernel学习笔记

    Linux Kernel 学习笔记涵盖了多个核心主题,包括存储器寻址、设备驱动程序开发等多个方面。下面是这些主题的详细解析: 1. **存储器寻址**: 在80x86架构中,存在三种存储器地址:逻辑地址、线性地址和物理地址。...

    Socket网络编程学习笔记之---使用线程池提高性能

    本篇学习笔记将深入探讨如何结合Socket与线程池来提升程序的运行效率。 一、Socket基础 Socket,也称为套接字,是网络编程中的一个重要概念,它是进程间通信(IPC)的一种方式,特别是在网络环境中。Socket提供了一...

    linux网络编程学习笔记

    在&lt;linux/socket.h&gt;;中有 sockaddr的定义 struct sockaddr{ unisgned short as_family; char sa_data[14]; }; 不过由于系统的兼容性,我们一般不用这个头文件,而使用另外一个结构(struct sock addr_in) 来代替...

    linux驱动程序设计学习笔记

    以上就是《Linux设备驱动程序》第三版学习笔记的主要内容,涵盖了Linux驱动开发的各个方面。通过深入学习和实践,你可以掌握构建高效、可靠的Linux驱动程序的技巧,为你的Linux开发事业奠定坚实的基础。

    Linux 应用开发流程详细笔记

    本笔记将深入探讨Linux应用开发的详细流程,包括操作系统接口的使用、网络通信、设备驱动以及用户界面的设计。以下是对每个主题的详细阐述: 1. **Linux操作系统接口**:Linux作为开源的操作系统,提供了丰富的API...

    嵌入式linux应用开发学习笔记.zip

    在"嵌入式Linux应用开发学习笔记.zip"这个压缩包中,我们可以预见到包含了一系列有关这一主题的学习资料,比如代码示例、教程文档或者项目实践。其中的"Embedded-Linux-master"可能是一个项目的源代码库,下面我们将...

    socket 编程基础(网络编程)思维导图-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

    socket编程是一种在Linux下的进程间通信机制,用于不同主机上或同一主机上应用程序之间的通信。它通常采用客户端与服务器的模式进行通信,多个客户端可以同时连接到服务器。开发人员通过调用内核提供的socket接口来...

    嵌入式linux入门笔记

    嵌入式Linux作为一门综合性极强的技术领域,...阿南的嵌入式Linux入门笔记可能涵盖了这些基础知识,通过深入学习和实践,初学者可以逐步掌握这个领域的核心概念和技术,为成为专业的嵌入式Linux开发者打下坚实基础。

    Linux网络编程socket编程学习

    自学Linux网络编程关于socket的编写,包括 server.c 和 client.c 的编写;很详细的介绍了网络套接字socket的C/S模型TCP协议的服务器端和客户端的程序函数以及编写过程;重点介绍多路I/O转接服务器的实现,包括select...

    Linux系统编程学习笔记

    ### Linux系统编程学习笔记 #### 一、IO **1.1 标准I/O (stdio)** - **fopen/fclose**: `fopen` 用于打开或创建一个文件,并返回一个指向该文件的 `FILE *` 类型的指针。`fclose` 用于关闭由 `FILE *` 指向的文件...

    Java+JDK6学习笔记

    本篇将围绕“Java+JDK6学习笔记”展开,探讨在JDK6环境下Java编程的核心知识点。 1. **JDK6概述**:JDK6是Oracle公司于2006年发布的Java平台标准版(Java SE)的一个重要版本,它的全称是Java SE 6,带来了许多新...

    linux学习笔记

    ### Linux学习笔记知识点详解 #### 一、认识命令行 - **热键切换**:`Ctrl+Alt+F1` 至 `F6` 可以切换到第一至第六控制台,而 `Alt+F7` 则可以切换回到图形界面。 - **Shell提示符**:在 Linux 中,管理员的提示符...

Global site tag (gtag.js) - Google Analytics