Linux下的socket编程

网络通信编程即编写通过计算机与其他程序之间进行通讯的程序,相互通信的程序中一方可以称为客户端程序,另一方称为服务程序,应用系统提供Socket编程接口可以编写自己的网络程序。

一  通过TCP/IP协议进行传输

TCP:为应用程序提供可靠的通信连接。适合一次传输大批的数据情况。并使用于要求得到的响应程序。

UDP:提供无线连接通信,且对传送包进行可靠性保证。适合一次传输少量的数据,可靠性则由应用层来负责。

二  Socket套接字

网络通信编程通过socket接口来进行的。socket接口是TCP/IP网络的API,包含了一整套的调用接口和数据结构定义,他给应用程序提供了如使用TCP/UDP等网络协议进行通讯的手段。

每一个socket都用一个半相关的描述(协议,本地地址,本地端口)来表示;一个完整的套接字则用一个相关描述(协议,本地地址,本地端口,远程地址,远程端口)来表示。

常见的socket有3种类型如下:

  1. 流式套接字socket(SOCK_STREAM)

流式套接字提供面向连接的,可靠的数据传输服务,数据无差错,无重复的发送,且按发送顺序接收.

2.数据报套接字socke(SOCK_DGRSM)

数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证是可靠,无差错的。

3原始套接字

允许对底层协议如IP或ICMP进行直接访问,它功能强大使用较为不便,主要用于一些协议的开发.

三 客户/服务模式

在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户机/服务器,及客户向服务器提出请求,服务器接收到请求后,提供相应的服务。

编程过程

服务器端:socket-bind-listen-accept-recv/recvfrom-send/sendto-close

#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 4321

#define BUFFER_SIZE 4024

#define MAX_QUE_CONN_NM 5

int main()

{

struct sockaddr_in server_addr,client_addr;

int sockfd,recvbytes;

int sin_size,client_fd;

char buffer[BUFFER_SIZE];

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

{

perror("socket");

exit(1);

}

server_addr.sin_family=AF_INET;

server_addr.sin_port=htons(PORT);

server_addr.sin_addr.s_addr=INADDR_ANY;

bzero(&(server_addr.sin_zero),8);

int i=1;

setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));

if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr))==-1)

{

perror("bind\n");

exit(1);

}

printf("bind success\n");

if(listen(sockfd,MAX_QUE_CONN_NM)==-1)

{

perror("listen\n");

exit(1);

}

printf("Listen......\n");

if((client_fd=accept(sockfd,(struct sockaddr *)&client_addr,&sin_size))==-1)

{

perror("recv\n");

exit(1);

}

printf("server get connection from %s\n",(char *)inet_ntoa(client_addr.sin_addr));

memset(buffer,0,sizeof(buffer));

if((recvbytes=recv(client_fd,buffer,BUFFER_SIZE,0))==-1)

{

perror("recv");

exit(1);

}

char *str1="hello server";

char *str2="hello ABC";

if(strncmp(buffer,str1,strlen(str1))==0)

{

printf("receive a message:%s\n",buffer);

send(client_fd,"hello client",12,0);

printf("send a message:hello client\n");

}

if(strncmp(buffer,"exit",4)==0)

{

exit(0);

close(sockfd);

}

}

客户端:socket-connect-send/sendto-recv/recvfrom-close

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<errno.h>

#include<sys/types.h>

#include<sys/socket.h>

#include<netinet/in.h>

#define MAXLINE 4096

int main(int argc, char** argv)

{

int    sockfd, n,rec_len;

char    recvline[4096], sendline[4096];

char    buf[MAXLINE];

struct sockaddr_in    servaddr;

if( argc != 2){

printf("usage: ./client <ipaddress>\n");

exit(0);

}

if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){

printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);

exit(0);

}

memset(&servaddr, 0, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_port = htons(4321);

if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){

printf("inet_pton error for %s\n",argv[1]);

exit(0);

}

if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){

printf("connect error: %s(errno: %d)\n",strerror(errno),errno);

exit(0);

}

printf("send msg to server: \n");

fgets(sendline, 4096, stdin);

if( send(sockfd, sendline, strlen(sendline), 0) < 0)

{

printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);

exit(0);

}

if((rec_len = recv(sockfd, buf, MAXLINE,0)) == -1) {

perror("recv error");

exit(1);

}

buf[rec_len]  = ‘\0‘;

printf("Received : %s ",buf);

close(sockfd);

exit(0);

}

时间: 2024-10-09 00:58:10

Linux下的socket编程的相关文章

Linux下的socket编程实践(十) 基本UDP编程细节

在我的这两篇博客中,简单介绍并实现了基于UDP(TCP)的windows(UNIX下流程基本一致)下的服务端和客户端的程序,本文继续探讨关于UDP编程的一些细节. http://blog.csdn.net/nk_test/article/details/47733307 http://blog.csdn.net/nk_test/article/details/47756381 下图是一个简单的UDP客户/服务器模型: 我在这里也实现了一个简单的UDP回射服务器/客户端: /**实践: 实现一个基

LINUX 下 ipv6 socket 编程

大家都知道,随着互联网上主机数量的增多,现有的32位IP地址已经不够用了,所以推出了下一代IP地址IPv6,写网络程序的要稍微改变一下现有的网络程序适应IPv6网络是相当容易的事.对于我们来说就是IP地址变化了,所以程序里在用到IP地址的地方做相应的改变就可以了. 记住:主要是改变程序里设置IP地址和端口等部分的代码. 服务器端源代码如下:/***********************/#include <stdio.h>#include <stdlib.h>#include &

Linux下的socket编程实践(八) Select的限制和poll(并发的初步知识)

select的限制 用select实现的并发服务器,能达到的并发数一般受两方面限制: 1)一个进程能打开的最大文件描述符限制.这可以通过调整内核参数来改变.可以通过ulimit -n(number)来调整或者使用setrlimit函数设置(需要root权限),但一个系统所能打开的最大数也是有限的,跟内存大小有关,可以通过cat /proc/sys/fs/file-max 查看. 2)select中的fd_set集合容量的限制(FD_SETSIZE,一般为1024),这需要重新编译内核才能改变.

Linux下的socket编程实践(四)TCP服务端优化和常见函数

并发下的僵尸进程处理 只有一个进程连接的时候,我们可以使用以下两种方法处理僵尸进程: 1)通过忽略SIGCHLD信号,避免僵尸进程 在server端代码中添加 signal(SIGCHLD, SIG_IGN); 2)通过wait/waitpid方法,解决僵尸进程 signal(SIGCHLD,onSignalCatch); void onSignalCatch(int signalNumber) { wait(NULL); } 那么如果是多进程状态下多个客户端同时关闭呢? 我们可以用下面的客户端

Linux下的socket编程实践(四)TCP的粘包问题和常用解决方案

TCP粘包问题的产生 由于TCP协议是基于字节流并且无边界的传输协议, 因此很有可能产生粘包问题.此外,发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一个TCP段.若连续几次需要send的数据都很少,通常TCP会根据优化算法把这些数据合成一个TCP段后一次发送出去,但是接收方并不知道要一次接收多少字节的数据,这样接收方就收到了粘包数据.具体可以见下图: 假设主机A send了两条消息M1和M2 各10k 给主机B,由于主机B一次提取的字节数

Linux下的socket编程实践(三)端口复用和 P2P多进程服务器

Socket端口复用 先说为什么要使用socket端口复用?如果你遇到过这样的问题:server程序重启之后,无法连接,需要过一段时间才能连接上? 1.一个监听(listen)server已经启动 2.当有client有连接请求的时候,server产生一个子进程去处理该client的事物. 3.server主进程终止了,但是子进程还在占用该连接处理client的事情.虽然子进程终止了,但是由于子进程没有终止,该socket的引用计数不会为0,所以该socket不会被关闭. 4.server程序重

网络编程学习笔记:linux下的socket编程

socket是进程通信的一种方式,通过调用一些API可以实现进程间通信,建立连接以及收发信息的过程如下图所示: 这些函数的用法如下: 1.int socket(int protocolFamily, int type, int protocol); 返回描述符sockfd l  protocolFamily:协议族,AF_INET(IPV4).AF_INET6(IPV6).AF_LOCAL(或称AF_UNIX,unix域socket).AF_ROUTE等.协议族决定了socket的地址类型,在通

Linux下的socket编程实践(一) 网络基本知识以及 TCP/IP简述

ISO/OSI七层参考模型 1.物理层:主要定义物理设备标准,如网线的接口类型.光纤的接口类型.各种传输介质的传输速率等.它的主要作用是传输比特流(就是由1.0转化为电流强弱来进行传输,到达目的地后再转化为1.0,也就是我们常说的数模转换与模数转换).这一层的数据叫做比特.(标志:RJ-45) 2.数据链路层:定义了如何让格式化数据以进行传输,以及如何让控制对物理介质的访问.这一层通常还提供错误检测和纠正,以确保数据的可靠传输,交换机属于本层. 3.网络层:在位于不同地理位置的网络中的两个主机系

Linux下TCP网络编程与基于Windows下C#socket编程间通信

一.linux下TCP网络编程基础,需要了解相关函数 Socket():用于套接字初始化. Bind():将 socket 与本机上的一个端口绑定,就可以在该端口监听服务请求. Listen():使socket处于被动的监听模式,并为该  socket  建立一个输入数据队列,将到达的服务器, 请求保存在此队列中,直到程序处理他们. Accept():让服务器接收客户的连接请求. Connect():客户端使用connect函数来配置 socket并与远端服务器建立一个 TCP 连接. Clos