socket通信之最简单的socket通信

http://blog.csdn.net/xluren/article/details/8043484#t15

套接字有三种类型

流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM)及原始套接字。

1.流式套接字提供面向连接、可靠的数据传输服务,数据按字节流、按顺序收发,保证在传输过程中无丢失、无冗余。TCP协议支持该套接字。

2.数据报套接字,提供面向无连接的服务,数据收发无序,不能保证数据的准确到达。UDP协议支持该套接字。

3.原始套接字原始套接字主要用于一些协议的开发,可以进行比较底层的操作。它功能强大,但是没有上面介绍的两种套接字使用方便,一般的程序也涉及不到原始套接字。

重要的几个结构体:

1.sockaddr

[cpp] view plain copy
  1. struct sockaddr  
  2. {  
  3.         unsigned short sa_family; /* address族, AF_xxx */  
  4.         char sa_data[14]; /* 14 bytes的协议地址 */  
  5. };  

sa_family 一般来说,都是“AFINET”。
sa_data 包含了一些远程电脑的地址、端口和套接字的数目,它里面的数据是杂溶在一切的。

由于在设置上面比较麻烦,所以有了一个更清晰的结构体数据

2.struct sockaddr_in

注:“in” 代表 “Internet”

[cpp] view plain copy
  1. struct sockaddr_in   
  2. {  
  3.         short int sin_family; /* Internet地址族 */  
  4.         unsigned short int sin_port; /* 端口号 */  
  5.         struct in_addr sin_addr; /* Internet地址 */  
  6.         unsigned char sin_zero[8]; /* 添0(和struct sockaddr一样大小)*/  
  7. };  

3.struct in_addr (Internet地址)

struct in_addr
{
 unsigned long s_addr;
};

一些函数:

1.socket

#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain , int type , int protocol);

说明:

domain 需要被设置为“AF_INET”;

type为套接字类型;

protocol为协议一般设置为0

2.bind()

#include <sys/types.h>
#include <sys/socket.h>
int bind (int sockfd , struct sockaddr *my_addr , int addrlen) ;
参数说明:
sockfd 是由socket()函数返回的套接字描述符。
my_addr 是一个指向struct sockaddr 的指针,包含有关你的地址的信息:名称、端口和IP 地址,可以将struct sockaddr_in结构体强制类型转换传入。
addrlen 可以设置为sizeof(struct sockaddr)。

3.connect()

#include <sys/types.h>
#include <sys/socket.h>
int connect (int sockfd, struct sockaddr *serv_addr, int addrlen);
参数说明:

sockfd :套接字文件描述符,由socket()函数返回的。
serv_addr 是一个存储远程计算机的IP 地址和端口信息的结构。
addrlen 应该是sizeof(struct sockaddr)。

4.listen()

#include <sys/socket.h>
int listen(int sockfd, int backlog);
参数说明:

sockfd 是一个套接字描述符,由socket()系统调用获得。
backlog 是未经过处理的连接请求队列可以容纳的最大数目。

5.accept()

#include <sys/socket.h>
int accept(int sockfd, void *addr, int *addrlen);
参数说明:

sockfd 是正在listen() 的一个套接字描述符。
addr 一般是一个指向struct sockaddr_in 结构的指针;里面存储着远程连接过来的计算机的信息(比如远程计算机的IP 地址和端口)。
addrlen 是一个本地的整型数值,在它的地址传给accept() 前它的值应该是sizeof(struct sockaddr_in);accept()不会在addr 中存储多余addrlen bytes 大小的数据。如果accept()函数在addr 中存储的数据量不足addrlen,则accept()函数会改变addrlen 的值来反应这个情况。

注:调用成功后返回一个标识符,被send或recv用来进行数据的接收和发送

6.send()

#include <sys/types.h>
#include <sys/socket.h>
int send(int sockfd, const void *msg, int len, int flags);
参数说明:
sockfd 是代表你与远程程序连接的套接字描述符。
msg 是一个指针,指向你想发送的信息的地址。
len 是你想发送信息的长度。
flags 发送标记。一般都设为0(你可以查看send 的man pages 来获得其他的参数值并且明白各个参数所代表的含义,很多时候只要你手不懒,通过linux的man命令可以获得很多详细的说明,另外很多书籍或者博客信息也都是man的中文翻译)。

7.recv()

#include <sys/types.h>
#include <sys/socket.h>
int recv(int sockfd, void *buf, int len, unsigned int flags);
参数说明:
sockfd 是你要读取数据的套接字描述符。
buf 是一个指针,指向你能存储数据的内存缓存区域。
len 是缓存区的最大尺寸。
flags 是recv() 函数的一个标志,一般都为0

到此你可以写出一个简单的c/s模式的通信来了。

c/s模式是面向连接的demo

server端:

[cpp] view plain copy
  1. <span style="font-size:14px;">#include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<string.h>  
  4. #include<errno.h>  
  5. #include<sys/types.h>  
  6. #include<sys/socket.h>  
  7. #include<netinet/in.h>  
  8. #define MAXLINE 4096  
  9. int main(int argc, char** argv)  
  10. {      
  11.         int    listenfd, connfd;      
  12.         struct sockaddr_in     servaddr;      
  13.         char    buff[4096];      
  14.         int     n;      
  15.         if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )  
  16.         {      
  17.                 printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);      
  18.                 exit(0);      
  19.         }      
  20.         memset(&servaddr, 0, sizeof(servaddr));      
  21.         servaddr.sin_family = AF_INET;      
  22.         servaddr.sin_addr.s_addr = htonl(INADDR_ANY);      
  23.         servaddr.sin_port = htons(6666);      
  24.         if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1)  
  25.         {      
  26.                 printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);      
  27.                 exit(0);      
  28.         }      
  29.         if( listen(listenfd, 10) == -1)  
  30.         {      
  31.                 printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);      
  32.                 exit(0);      
  33.         }        
  34.         printf("======waiting for client's request======\n");      
  35.         while(1)  
  36.         {      
  37.                 if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1)  
  38.                 {          
  39.                         printf("accept socket error: %s(errno: %d)",strerror(errno),errno);          
  40.                         continue;      
  41.                 }      
  42.                 n = recv(connfd, buff, MAXLINE, 0);      
  43.                 buff[n] = '\0';      
  44.                 printf("recv msg from client: %s\n", buff);      
  45.                 close(connfd);      
  46.         }      
  47.         close(listenfd);  
  48. }</span>  

client端:

[cpp] view plain copy
  1. <span style="font-size:14px;">#include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<string.h>  
  4. #include<errno.h>  
  5. #include<sys/types.h>  
  6. #include<sys/socket.h>  
  7. #include<netinet/in.h>  
  8. #define MAXLINE 4096  
  9. int main(int argc, char** argv)  
  10. {      
  11.         int    sockfd, n;      
  12.         char    recvline[4096], sendline[4096];      
  13.         struct sockaddr_in    servaddr;      
  14.         if( argc != 2)  
  15.         {      
  16.                 printf("usage: ./client <ipaddress>\n");      
  17.                 exit(0);      
  18.         }      
  19.         if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)  
  20.         {     
  21.                 printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);      
  22.                 exit(0);      
  23.         }      
  24.         memset(&servaddr, 0, sizeof(servaddr));      
  25.         servaddr.sin_family = AF_INET;      
  26.         servaddr.sin_port = htons(6666);      
  27.         if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)  
  28.         {      
  29.                 printf("inet_pton error for %s\n",argv[1]);      
  30.                 exit(0);      
  31.         }      
  32.         if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)  
  33.         {      
  34.                 printf("connect error: %s(errno: %d)\n",strerror(errno),errno);      
  35.                 exit(0);      
  36.         }      
  37.         printf("send msg to server: \n");     
  38.         
  39.  while(1)
  40. {
  41.   fgets(sendline, 4096, stdin);     
  42.  if( send(sockfd, sendline, strlen(sendline), 0) < 0)     
  43.  {          
  44.          printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);     
  45.                 exit(0);      
  46.         }     

  47. }
  48.         close(sockfd);      
  49.         exit(0);  
  50. }  
  51. </span>  

  1.   fgets(sendline, 4096, stdin);      
  2.         if( send(sockfd, sendline, strlen(sendline), 0) < 0)      
  3.         {      
  4.                 printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);      
  5.                 exit(0);      
  6.         }     

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383849.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java环境配置

自己安装的时候按照一般的安装方法先配置了JDK的环境&#xff0c;能够成功显示java版本后我在安装eclipse的时候一直提示错误&#xff1a; Unfortunately the Java version needed to run Eclipse Installer couldn’t be found on your system. You need the following versio…

Linux I/O复用之select函数详解

http://blog.csdn.net/y396397735/article/details/55004775 select函数的功能和调用顺序 使用select函数时统一监视多个文件描述符的&#xff1a; 1、 是否存在套接字接收数据&#xff1f; 2、 无需阻塞传输数据的套接字有哪些? 3、 哪些套接字发生了异常&#xff1f; sel…

【Java学习笔记一】类和对象

面向对象程序设计的一个一个重要特点是&#xff1a;封装性。 这里的封装性有两方面含义&#xff1a;一是将有关的数据和操作代码封装在一个对象中形成一个基本单位&#xff0c;各个对象之间相互独立互不干扰&#xff0c;二是将对象中某些部分对外隐蔽&#xff0c;即隐蔽其内部细…

深入研究socket编程(3)——使用select函数编写客户端和服务器

http://blog.csdn.net/chenxun_2010/article/details/50488394 首先看原先《UNIX网络编程——并发服务器&#xff08;TCP&#xff09;》的代码&#xff0c;服务器代码serv.c&#xff1a; [cpp] view plaincopy #include<stdio.h> #include<sys/types.h> #inclu…

Java简单输入输出

不同于面向过程中有直接的输入输出函数&#xff0c;Java中的输入输出只能通过类来实现。 比较常见的一种是使用Scanner类 需要引入java.util包&#xff0c;即在文件开始加上语句import java.util.*;创建Scanner类对象&#xff0c;属于标准输入流。 例如Scanner snew Scanner(S…

Ubuntu安装搭建Clion环境

呜呜呜&#xff0c;太辛苦了&#xff0c;我终于安装好这个了。 大概过程就是先在官网下载安装包&#xff0c;然后解压以后用终端移动到对应文件夹下运行clin.sh 运行完以后会有一些窗口&#xff0c;第一个选择don’t~~&#xff0c;然后点击ok 接受&#xff08;你可以不接受…

UNIX网络编程——select函数的并发限制和 poll 函数应用举例

http://blog.csdn.net/chenxun_2010/article/details/50489577 一、用select实现的并发服务器&#xff0c;能达到的并发数&#xff0c;受两方面限制 1、一个进程能打开的最大文件描述符限制。这可以通过调整内核参数。可以通过ulimit -n来调整或者使用setrlimit函数设置&#x…

【Java学习笔记二】继承和多态

与C不同的是&#xff0c;在Java中&#xff0c;一个类只能直接继承另一个类&#xff0c;而不允许继承多个类&#xff0c;这个新类称为继承类、派生类或者子类&#xff0c;而被继承的类称为基类或者父类。 继承类能够继承基类的群不属性和行为。 面向对象程序设计的三大特点为&…

使用poll实现的io多路复用服务端和客户端

http://blog.csdn.net/robertkun/article/details/52269313 参考&#xff1a;http://www.cnblogs.com/Anker/p/3261006.html 使用poll实现的io多路复用服务端和客户端。 客户端通过子进程创建多个客户端连接。 客户端每隔1秒向服务端发送一个时间戳&#xff0c; 服务端接收到时…

【Java学习笔记三】抽象类与接口

对象的类型转换分为自动转换和强制转换两种 派生类向基类转换是自动转换&#xff0c;因为派生类中包含基类基类向派生类的转换是强制转换 强制类型转换是通过在转换对象前面使用圆括号运算符来实现&#xff0c;圆括号内为要转换的目标类型&#xff0c;格式为&#xff1a; (&…

Epoll 的tcp通信代码(服务器+客户端)

http://blog.csdn.net/libinbin_1014/article/details/50096187 Epoll 的tcp通信代码&#xff08;服务器客户端&#xff09; /* gcc -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS64 -I${ORACLE_HOME}/rdbms/public -I${ORACLE_HOME}/rdbms/demo -L${ORACLE_HOME}/lib -lclntsh …

【Java学习笔记四】Java中的包

包的声明和引入&#xff1a;在Java语言系统中&#xff0c;Java编译器为每一个类生成一个字节码文件&#xff08;.class&#xff09;&#xff0c;为了对类文件进行分层和按用途分类管理&#xff0c;同时也为了解决相同类名的文件冲突的问题&#xff0c;Java提供了包机制来管理类…

Linux系统编程——线程池

http://blog.csdn.net/tennysonsky/article/details/46490099# 线程池基本原理 在传统服务器结构中&#xff0c;常是有一个总的监听线程监听有没有新的用户连接服务器&#xff0c;每当有一个新的用户进入&#xff0c;服务器就开启一个新的线程用户处理这 个用户的数据包。这个线…

【Java学习笔记五】Java异常处理

异常通常分为三类&#xff1a; 程序可控制的异常&#xff1a;一般是可预见的错误&#xff0c;不是致命的。例如&#xff1a;除数为0&#xff0c;数组下标越界。程序不可控制的的异常&#xff1a;这种异常往往是致命的&#xff0c;但是系统可以预见的。例如&#xff1a;系统栈溢…

【C++学习笔记一】C++类和对象详解

类定义是以关键字class开头&#xff0c;后面跟类的名称。主体是包含在一对花括号中。类定义后必须跟着一个分号或一个声明列表。 类的对象的公共数据成员可以使用直接成员访问运算符.来访问。需要注意的是&#xff0c;私有的成员和受保护的成员不能直接使用成员访问运算符来访…

C语言实现的简单的线程池

http://www.linuxidc.com/Linux/2013-01/77619.htm 有时我们会需要大量线程来处理一些相互独立的任务&#xff0c;为了避免频繁的申请释放线程所带来的开销&#xff0c;我们可以使用线程池。下面是一个C语言实现的简单的线程池。 头文件&#xff1a; 1: #ifndef THREAD_POOL_H_…

C++获取当前时间

可以使用windowsAPI直接获取。 例如&#xff1a; #include<windows.h> #include<cstdio>using namespace std;int main() {SYSTEMTIME now;GetLocalTime(&now);printf("现在是%02d时%02d分%02d秒\n",now.wHour,now.wMinute,now.wSecond);printf(&…

成员函数后面加上const的作用

const表示成员函数不会修改类中的数据成员。 规则&#xff1a; 在类中被const 声明的函数只能访问const 函数&#xff0c;而非const 函数可以访问任意成员函数。在成员函数中不管数据是否具有const 属性&#xff0c;编译器检查的的是是否有修改&#xff08;赋值&#xff0c;自…

简单Linux C线程池

http://www.cnblogs.com/venow/archive/2012/11/22/2779667.html 大多数的网络服务器&#xff0c;包括Web服务器都具有一个特点&#xff0c;就是单位时间内必须处理数目巨大的连接请求&#xff0c;但是处理时间却是比较短的。在传统的多线程服务器模型中是这样实现的&#xff1…

C++创建对象:栈和堆的区别

首先我们应该了解栈和堆的差别&#xff1a; 详细信息&#xff1a;传送门 栈相当于函数自带的存储空间&#xff0c;在windows下一般为2M,在Linux下一般为8M&#xff0c;存取速度稍微快一点。堆是系统的空间&#xff0c;相对较大&#xff0c;一般为2G&#xff0c;效率稍微慢一点…