Linux下的TCP Socket通信

一、socket函数

1、头文件:

#include <sys/types.h> /* See NOTES */

#include <sys/socket.h>

2、函数原型:

int socket(int domain, int type, int protocol);

socket函数类似于open,用来打开一个网络连接,如果成功则返回一个网络文件描述符(int类型),之后我们操作这个网络连接都通过这个网络文件描述符。

dimain:域,网络域,网络地址范围(IPV4或IPV6等),也就是协议簇

type:指定套接字类型:SOCK_STREAM(TCP网络)、SOCK_DGRAM(UDP)、SOCK_SEQPACKET

protocol:指定协议,如果指定0,表示使用默认的协议

3、函数形参:

3.1、domain:(域)

AF_INET      ip

AF_INET6    ipv6

AF_PACKET      
  packet         低级数据包接口

PF_PACKET   不懂,待了解

PF_INET      待了解(AF开头的表示地址族,PF开头的表示协议族,协议族包含多个地址族,但是当前这种还从未实现,而在<sys/socket.h>中PF的值总是与AF的值相等的)

3.2、type:(套接字类型):

SOCK_RAW      原始套接字     ——>使用原始套接字时候调用,原始套接字也就是链路层协议

SOCK_STREAM    字节流套接字  
 ——>提供顺序,可靠,双向,基于连接的字节流。 可以支持带外数据传输机制。例如:TCP协议、FTP协议

SOCK_DGRAM         数据报套接字    ——>支持数据报(无连接,不可靠的固定最大长度的消息)例如:UDP协议

SOCK_SEQPACKET   有序分组套接字    ——>为固定最大长度的数据报提供有序,可靠,双向连接的数据传输路径; 消费者需要利用每个输入系统调用读取整个分组

3.3、protocol(协议):

IPPROTO_IP       IP传输协议

IPPROTO_TCP      TCP传输协议

IPPROTO_UDP       UDP协议

IPPROTO_SCTP      SCTP传输协议

IPPROTO_ICMP      
   ICMP协议

IPPROTO_IGMP      IGMP协议

一般情况下IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP协议用的最多,UDP协议protocol就取IPPROTO_UDP,TCP协议protocol就取IPPROTO_TCP;一般情况下,我们让protocol等于0就可以,系统会给它默认的协议。但是要是使用raw socket协议,protocol就不能简单设为0,要与type参数匹配.

4、返回值:

成功时返回一个小的非负整数值,他与文件描述符类似,我们称为套接字描述符,简称sockfd。失败,则返回-1。

5、例子:

/*---------------------创建一个监听socket-------------------*/

if ((listenfd =
socket(AF_INET, SOCK_STREAM, 0)) == -1)

{

perror("socket() error\n");

exit(1);

}

二、bind函数

1、头文件:

#include <sys/types.h> /* See NOTES */

#include <sys/socket.h>

2、函数原型:

int bind(int sockfd, const struct sockaddr *addr,socklen_t
addrlen);

服务端套接字绑定自己的IP地址与端口号,客户端那边可以不写,内核会给它分配一个临时的端口。

3、函数形参:

3.1、sockfd:服务器或者客户端自己创建的socket

3.2、addr:服务器或者客户端自己的地址信息(协议族、IP、端口号)

3.3、addrlen:服务器或者客户端自己的地址信息的长度

4、返回值:

绑定成功,返回0,失败返回-1

5、例子:

    /*---------------------绑定IP和端口bind----------------------*/

    bzero(&server, sizeof(server));

    server.sin_family = AF_INET;

    server.sin_port = htons(port);

    server.sin_addr.s_addr = inet_addr(ip);

 

    if (bind(listenfd, (struct sockaddr
*)&server, sizeof(server)) == -1)

    {

        perror("bind() error\n");

        exit(1);

    }

三、connect函数

1、头文件:

#include <sys/types.h> /* See NOTES */

#include <sys/socket.h>

2、函数原型:

int connect(int sockfd, const struct sockaddr
*addr,socklen_t addrlen);

TCP客户端通过connect函数与服务端连接,进行通信。

3、函数形参:

3.1、sockfd(客户端自己创建的sock)

3.2、addr(服务端地址族、服务端IP地址、服务端端口号)

3.3、addrlen(服务端地址字节长度)

4、返回值:

连接成功,返回0,连接失败,返回-1

5、例子:

struct sockaddr_in client;

addrlen = sizeof(client);

if ((connetfd
= accept(listenfd, (struct sockaddr *)&client, &addrlen)) == -1)

{

perror("accept() error\n");

exit(1);

}

接下来给出一个大例子,tcp——socket套接字通信,结合sqlite3数据库操作

#include <stdio.h>

#include <stdlib.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/types.h>

#include <unistd.h>

#include <string.h>

int main()

{

struct sockaddr_in
server;

struct sockaddr_in
client;

int listenfd,
connetfd;

char ip[20];

int port;

int addrlen;

char rebuf[100];

char wrbuf[100];

char tmp[100];

int revlen;

/*---------------------创建一个监听socket-------------------*/

if ((listenfd = socket(AF_INET,
SOCK_STREAM, 0)) == -1)

{

perror("socket()
error\n");

exit(1);

}

/*----------------------输入要监听的IP和端口----------------------*/

printf("Please
input the ip:\n");

scanf("%s", ip);

printf("Please
input the port:\n");

scanf("%d", &port);

/*---------------------绑定IP和端口bind----------------------*/

bzero(&server, sizeof(server));

server.sin_family = AF_INET;

server.sin_port = htons(port);

server.sin_addr.s_addr = inet_addr(ip);

if (bind(listenfd, (struct sockaddr
*)&server, sizeof(server)) == -1)

{

perror("bind()
error\n");

exit(1);

}

/*----------------------开始监听listen-------------------*/

if (listen(listenfd, 20) == -1)

{

perror("listen()
error\n");

exit(1);

}

int client_pid = 0;

while (1)

{

/*----------------------accept------------------*/

addrlen = sizeof(client);

if ((connetfd = accept(listenfd, (struct sockaddr
*)&client, &addrlen)) == -1)

{

perror("accept()
error\n");

exit(1);

}

/*---------------------show
client---------------*/

printf("connect
successful!\n");

printf("the client
ip is %s,port is %d\n", inet_ntoa(client.sin_addr), ntohs(port));

client_pid = fork();

if (client_pid == 0)

{

//子进程

close(listenfd); //关闭监听请求

/*----------------------read
and write----------*/

int serial = 0;

while (1)

{

bzero(rebuf, sizeof(rebuf));

revlen = read(connetfd,
rebuf, sizeof(rebuf));

if ((memcmp("bye", rebuf, 3)) == 0)

{

printf("Bye-bye
then close the connect...\n");

break;

}

bzero(wrbuf, sizeof(wrbuf));

bzero(tmp, sizeof(tmp));

sprintf(tmp, "%d", serial);

strcat(tmp, rebuf);

bcopy(tmp, wrbuf, strlen(tmp));

write(connetfd,
wrbuf, sizeof(wrbuf));

rebuf[revlen] = ‘\0‘;

printf("the info
from client is:%s\n", rebuf);

serial++;

}

return 0;

}

close(connetfd); //父进程关闭连接请求

}

return 0;

}

原文地址:https://www.cnblogs.com/GotWindy/p/11066976.html

时间: 2024-10-04 08:18:53

Linux下的TCP Socket通信的相关文章

Linux下简单的socket通信实例

Linux下简单的socket通信实例 If you spend too much time thinking about a thing, you’ll never get it done. —Bruce Lee       学习网络编程也一段时间了,刚开始看<UNIX网络编程>的时候,觉得这本厚厚的书好难啊!看到后来,发现并没有想象中的那么难.如果你是新手,建议你看到第二部分结束后,开始着手写代码.不写代码肯定是不行的.看100遍也没有敲一遍实现一遍来的清楚.敲完以后,带着问题去看书,你会

Linux下进程间Socket通信调试debug方法

在一个复杂的软件系统中,往往需要有各个组件之间的数据传递,在组件间数据传递过程中,又会不可避免的出现一些小问题,这时候我们就需要来进行debug了,由于最近的一个系统使用到了collectd和rrdcached来收集数据和画图,它们之间采用了Unix socket通信,因此小小的学习了一下相关知识. 首先我们来回忆下Linux下进程通信有哪些方法: 管道(Pipe)及有名管道(FIFO)\UNIX BSD 信号(Signal) \UNIX BSD 报文消息队列(Message)\UNIX sys

linux下C语言socket网络编程简例

转自:http://blog.csdn.net/kikilizhm/article/details/7858405 这里给出在linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到客户端的连接后,发送数据给客户端:客户端在接受到数据后打印出来,然后关闭.程序里有详细的说明,其中对具体的结构体和函数的实现可以参考其他资料. 程序说明: 这里服务器的端口号和ip地址使用固定的设置,移植时可以根据具体情况更改,可以改写为参数传递更好,这里为了方便,使用固定的. 移

Linux下高并发socket最大连接数所受的各种限制(详解)

1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也是一个文件句柄).可使用ulimit命令查看系统允许当前用户进程打开的文件数限制: [[email protected] ~]$ ulimit -n1024 这表示当前用户的每个进程最多允许同时打开1024个文件,这1024个文件中

Linux下高并发socket链接数测试

一.如何增大service进程的max open files ulimit -n 只能改小max open files,不能改大.需要按照以下步骤: 修改/etc/security/limits.conf文件,将"soft nofile 655360"和"hard nofile 655360"这两行的655360改成期望的值 退出,重新ssh该机器(否则无效) 修改对service的启动脚本,增加"ulimit -n 950000",其中9500

基于Java的TCP Socket通信详解(计算机端/Android手机端)

TCP Socket通信是一种比较常用的基于连接的网络通信方式.本文通过Java实现TCP Socket通信,并将其用于计算机端.Android手机端,同时做到代码规范化,实现代码最大化复用. 本文代码可在GitHub下载,建议对照源码阅读文章 https://github.com/jzj1993/JavaTcpSocket TCP连接的建立 客户端和服务器间通过三次握手建立TCP连接.在Java中,连接建立完成后,服务器端和客户端分别获取到一个Socket实例,之后就可以通过这个Socket实

【Java TCP/IP Socket】TCP Socket通信中由read返回值造成的的死锁问题(含代码)

书上示例 在第一章<基本套接字>中,作者给出了一个TCP Socket通信的例子——反馈服务器,即服务器端直接把从客户端接收到的数据原原本本地反馈回去. 书上客户端代码如下: import java.net.Socket; import java.net.SocketException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class TCPEch

Linux C++ TCP Socket通信实例

环境:Linux 语言:C++ 通信方式:TCP 下面用TCP协议编写一个简单的服务器.客户端,其中服务器端一直监听本机的6666号端口.如果收到连接请求,将接收请求并接收客户端发来的消息:客户端与服务器端建立连接并发送一条消息. server.cpp 1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<errno.h> 5 #include<sys/type

linux下close 掉socket 之后 阻塞的recv 不会立即返回

在开发的一个基于rtmp聊天的程序时发现了一个很奇怪的现象. 在windows下当我们执行 closesocket 的操作之后,阻塞的 recv 会立即返回 -1 . 而在linux 下 当我们执行 close 操作之后 阻塞的recv 会出现不能立即返回的现象.后来在网上一搜发现很多遇到类似这种现象的情况,大致意思应该是 当socket 被动被close 的时候 进入了 “CLOSE_WAIT(被动关闭一方)” 的情况. 解决方法就是 在你close 之前调用一下 : shutdown(soc