本文目录
- 关于Linux下socket编程的问题
- socket编程在windows和linux下的区别
- socket编程在windows和linux下的区别是什么
- linux下的 socket编程问题!
- Linux操作系统下Socket编程地址结构介绍
- Linux下C语言socket编程
- linux下的socket编程在哪进行
- LINUX网络编程中socket函数详细解释下吧
- Linux下socket编程的sockaddr_in结构体中的__SOCKADDR_COMMON (sin_);是什么意思
关于Linux下socket编程的问题
recv 函数,不能保证接受到所有你需要的数据包因此要反复调用recv函数. 并查看函数的返回值比如,你需要接受5000字节datalen=0while datalen《5000 ret=recv(...) datalen+=ret....因为recv这样的特性,所以你并不能保证每次recv收到的数据包是一个完整的, 它可能包含了服务器一次发送数据包的一部分,也可能包括了服务器先后几次发送的几个数据包。因此,你必须自己设计传输协议,能够明确的分辨服务器发送过来的每个数据包(比如每个数据包都有一个明显的结尾,或者数据包头加上数据包的长度)
socket编程在windows和linux下的区别
下面大概分几个方面进行罗列: Linux要包含 [cpp] #include 《sys/socket.h》 #include 《netinet/in.h》 #include 《netdb.h》 #include 《arpa/inet.h》 等头文件,而windows下则是包含 [cpp] #include 《winsock.h》 。 Linux中socket为整形,Windows中为一个SOCKET。 Linux中关闭socket为close,Windows中为closesocket。 Linux中有变量socklen_t,Windows中直接为int。 因为linux中的socket与普通的fd一样,所以可以在TCP的socket中,发送与接收数据时,直接使用read和write。而windows只能使用recv和send。 设置socet选项,比如设置socket为非阻塞的。Linux下为 [cpp] flag = fcntl (fd, F_GETFL); fcntl (fd, F_SETFL, flag | O_NONBLOCK); ,Windows下为 [cpp] flag = 1; ioctlsocket (fd, FIONBIO, (unsigned long *) &flag); 。 当非阻塞socket的TCP连接正在进行时,Linux的错误号为EINPROGRESS,Windows的错误号为WSAEWOULDBLOCK。 file Linux下面,文件换行是“\n“,而windows下面是“\r\n“。 Linux下面,目录分隔符是“/“,而windows下面是“\“。 Linux与Windows下面,均可以使用stat调用来查询文件信息。但是,Linux只支持2G大小,而Windows只支持4G大小。为了支持更大的文件查询,可以在Linux环境下加 _FILE_OFFSET_BITS=64定义,在Windows下面使用_stat64调用,入参为struct __stat64。 Linux中可根据stat的st_mode判断文件类型,有S_ISREG、S_ISDIR等宏。Windows中没有,需要自己定义相应的宏,如 [cpp] #define S_ISREG(m) (((m) & 0170000) == (0100000)) #define S_ISDIR(m) (((m) & 0170000) == (0040000)) Linux中删除文件是unlink,Windows中为DeleteFile。 time Linux中,time_t结构是长整形。而windows中,time_t结构是64位的整形。如果要在windows始time_t为32位无符号整形,可以加宏定义,_USE_32BIT_TIME_T。 Linux中,sleep的单位为秒。Windows中,Sleep的单位为毫秒。即,Linux下sleep (1),在Windows环境下则需要Sleep (1000)。 Windows中的timecmp宏,不支持大于等于或者小于等于。 Windows中没有struct timeval结构的加减宏可以使用,需要手动定义: [cpp] #define MICROSECONDS (1000 * 1000) #define timeradd(t1, t2, t3) do { \ (t3)-》tv_sec = (t1)-》tv_sec + (t2)-》tv_sec; \ (t3)-》tv_usec = (t1)-》tv_usec + (t2)-》tv_usec % MICROSECONDS; \ if ((t1)-》tv_usec + (t2)-》tv_usec 》 MICROSECONDS) (t3)-》tv_sec ++; \ } while (0) #define timersub(t1, t2, t3) do { \ (t3)-》tv_sec = (t1)-》tv_sec - (t2)-》tv_sec; \ (t3)-》tv_usec = (t1)-》tv_usec - (t2)-》tv_usec; \ if ((t1)-》tv_usec - (t2)-》tv_usec 《 0) (t3)-》tv_usec --, (t3)-》tv_usec += MICROSECONDS; \ } while (0) 调用进程 Linux下可以直接使用system来调用外部程序。Windows最好使用WinExec,因为WinExec可以支持是打开还是隐藏程序窗口。用WinExec的第二个入参指明,如 SW_SHOW/SW_HIDE。 杂项 Linux为srandom和random函数,Windows为srand和rand函数。 Linux为snprintf,Windows为_snprintf。 同理,Linux中的strcasecmp,Windows为_stricmp。 错误处理 Linux下面,通常使用全局变量errno来表示函数执行的错误号。Windows下要使用GetLastError ()调用来取得。 Linux环境下仅有的 这些函数或者宏,Windows中完全没有,需要用户手动实现。 atoll [cpp] long long atoll (const char *p) { int minus = 0; long long value = 0; if (*p == ’-’) { minus ++; p ++; } while (*p 》= ’0’ && *p 《= ’9’) { value *= 10; value += *p - ’0’; p ++; } return minus ? 0 - value : value; } gettimeofday [cpp] #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) #define EPOCHFILETIME 11644473600000000Ui64 #else #define EPOCHFILETIME 11644473600000000ULL #endif struct timezone { int tz_minuteswest; int tz_dsttime; }; int gettimeofday (struct timeval *tv, struct timezone *tz) { FILETIME ft; LARGE_INTEGER li; __int64 t; static int tzflag; if (tv) { GetSystemTimeAsFileTime (&ft); li.LowPart = ft.dwLowDateTime; li.HighPart = ft.dwHighDateTime; t = li.QuadPart; /* In 100-nanosecond intervals */ t -= EPOCHFILETIME; /* Offset to the Epoch time */ t /= 10; /* In microseconds */ tv-》tv_sec = (long) (t / 1000000); tv-》tv_usec = (long) (t % 1000000); } if (tz) { if (!tzflag) { _tzset (); tzflag++; } tz-》tz_minuteswest = _timezone / 60; tz-》tz_dsttime = _daylight; } return 0; } 编译相关 当前函数,Linux用__FUNCTION__表示,Windows用__func__表示。 -------------------------------------------------------------------------------- Socket 编程 windows到Linux代码移植遇到的问题 1)头文件 windows下winsock.h/winsock2.h linux下sys/socket.h 错误处理:errno.h 2)初始化 windows下需要用WSAStartup linux下不需要 3)关闭socket windows下closesocket(...) linux下close(...) 4)类型 windows下SOCKET linux下int 如我用到的一些宏: #ifdef WIN32 typedef int socklen_t; typedef int ssize_t; #endif #ifdef __LINUX__ typedef int SOCKET; typedef unsigned char BYTE; typedef unsigned long DWORD; #define FALSE 0 #define SOCKET_ERROR (-1) #endif 5)获取错误码 windows下getlasterror()/WSAGetLastError() linux下errno变量 6)设置非阻塞 windows下ioctlsocket() linux下fcntl() 《fcntl.h》 7)send函数最后一个参数 windows下一般设置为0 linux下最好设置为MSG_NOSIGNAL,如果不设置,在发送出错后有可 能会导致程序退出。 8)毫秒级时间获取 windows下GetTickCount() linux下gettimeofday() 3、多线程 多线程: (win)process.h --〉(linux)pthread.h _beginthread --》 pthread_create _endthread --》 pthread_exit ----------------------------------------------------------------- windows与linux平台使用的socket均继承自Berkeley socket(rfc3493),他们都支持select I/O模型,均支持使用getaddrinfo与getnameinfo实现协议无关编程。但存在细微差别, 主要有: 头文件及类库。windows使用winsock2.h(需要在windows.h前包含),并要链接库ws2_32.lib;linux使用netinet/in.h, netdb.h等。 windows下在使用socket之前与之后要分别使用WSAStartup与WSAClean。 关闭socket,windows使用closesocket,linux使用close。 send*与recv*函数参数之socket长度的类型,windows为int,linux为socklen_t,可预编译指令中处理这一差异,当平台为windows时#define socklen_t unsigned int。 select函数第一个参数,windows忽略该参数,linux下该参数表示集合中socket的上限值,一般设为sockfd(需select的socket) + 1。 windows下socket函数返回值类型为SOCKET(unsigned int),其中发生错误时返回INVALID_SOCKET(0),linux下socket函数返回值类型int, 发生错误时返回-1。 另外,如果绑定本机回环地址,windows下sendto函数可以通过,linux下sendto回报错:errno=22, Invalid arguement。一般情况下均绑定通配地址。转载jlins
socket编程在windows和linux下的区别是什么
1.头文件windows下winsock.h或winsock2.hlinux下netinet/in.h(大部分都在这儿),unistd.h(close函数在这儿),sys/socket.h(在in.h里已经包含了,可以省了)2.初始化windows下需要用WSAStartup启动Ws2_32.lib,并且要用#pragmacomment(lib,“Ws2_32“)来告知编译器链接该lib。linux下不需要3.关闭socketwindows下closesocket(...)linux下close(...)4.类型windows下SOCKETlinux下int5.获取错误码windows下getlasterror()/WSAGetLastError()linux下,未能成功执行的socket操作会返回-1;如果包含了errno.h,就会设置errno变量6.设置非阻塞windows下ioctlsocket()linux下fcntl(),需要头文件fcntl.h7.send函数最后一个参数windows下一般设置为0linux下最好设置为MSG_NOSIGNAL,如果不设置,在发送出错后有可能会导致程序退出8.毫秒级时间获取windows下GetTickCount()linux下gettimeofday()
linux下的 socket编程问题!
第一个问题:对,是那样的,用open打开文件,用read读取文件,在发送给对方,接收方接收到后,写入文件就可以了。不过在这个过程中最好别用字符串函数,除非你很熟悉。第二个问题首先你得去搞清楚什么是线程,什么是进程,fork出来的叫进程,pthread_create出来的才叫线程。服务器有很多种模型(多进程,多线程,select,epoll模型,这个我的blog上有,famdestiny.cublog.cn),不一定要用多进程。给你写了个代码,自己先看看:注意,在自己的目录下创建一个叫pserverb的文件,程序会把这个文件复制成test文件。你可以自己根据需要改改server:#include 《stdio.h》#include 《sys/socket.h》#include 《netinet/in.h》#include 《errno.h》#include 《signal.h》#include 《sys/wait.h》#include 《sys/types.h》#include 《string.h》#include 《stdlib.h》#include 《sys/stat.h》#include 《fcntl.h》#include 《unistd.h》#define SERV_PORT 5358#define MAX_CONN 10#define BUF_LEN 1024void str_echo(FILE *fp, int sockfd){ ssize_t nread; int file_fd; char buf[BUF_LEN] = {0}; file_fd = open(“test“, O_WRONLY | O_TRUNC | O_CREAT, 0755); while(1) { bzero(buf, BUF_LEN); if((nread = read(sockfd, buf, BUF_LEN)) == -1) { if(errno == EINTR) { continue; } else { printf(“readn error: %s\n“, strerror(errno)); continue; } } else if (nread == 0) { break; } else { printf(“%s\n“, buf); write(file_fd, buf, nread); } } close(file_fd); }void sig_chld(int sig){ pid_t pid; int state; while((pid = waitpid(-1, &state, WNOHANG)) 》 0){ printf(“child process %d exited.“, pid); } return;}int main(int argc, char **argv){ int listenfd, connfd; socklen_t cliaddrlen; pid_t childpid; struct sockaddr_in servaddr, cliaddr; if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ printf(“socket error: %s\n“, strerror(errno)); return 0; } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1){ printf(“bind error: %s\n“, strerror(errno)); return 0; } if(listen(listenfd, MAX_CONN) == -1){ printf(“listen error: %s\n“, strerror(errno)); return 0; } signal(SIGCHLD, sig_chld); while(1){ cliaddrlen = sizeof(cliaddr); if((connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddrlen)) == -1){ if(errno == EINTR){ continue; } else{ printf(“accept error: %s\n“, strerror(errno)); continue; } } if((childpid = fork()) == 0){ close(listenfd); str_echo(stdin, connfd); exit(0); } else if(childpid 》 0){ close(connfd); } else{ printf(“fork error!\n“); continue; } }}client:#include 《stdio.h》#include 《unistd.h》#include 《errno.h》#include 《sys/socket.h》#include 《netinet/in.h》#include 《arpa/inet.h》#include 《string.h》#include 《sys/stat.h》#include 《fcntl.h》#include 《stdlib.h》#define SERV_ADDR “127.0.0.1“#define SERV_PORT 5358#define BUF_LEN 1024void str_cli(char *path, int sockfd){ char sendbuf[BUF_LEN] = {0}; int fd, n; if((fd = open(“./pserverb“, O_RDONLY)) == -1){ printf(“%s\n“, strerror(errno)); exit(0); } while((n = read(fd, sendbuf, BUF_LEN)) != 0) { if(n 《 0){ printf(“%s\n“, strerror(errno)); exit(0); } write(sockfd, sendbuf, n); bzero(sendbuf, BUF_LEN); } close(fd); return;}int main(int argc, char **argv){ int fd; struct sockaddr_in servaddr; fd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr(SERV_ADDR); servaddr.sin_port = htons(SERV_PORT); if (connect(fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { printf(“connect error: %s\n“, strerror(errno)); return 0; } str_cli(argv, fd); return 0;}
Linux操作系统下Socket编程地址结构介绍
linux下的网络通信程序,一定要和一个结构打交道,这个结构就是socketaddress。比如bind、connect等等函数都要使用socketaddress结构。理解socketaddress时我们要明白,其实在linux下针对于不同的socketdomain定义了一个通用的地址结构structsockaddr,它的具体定义为:{unsignedshortintsa_family;charsa_data;}structsockaddr其中,sa_family为调用socket()函数时的参数domain参数,sa_data为14个字符长度存储。针对于不同domain下的socket,通用地址结构又对应了不同的定义,例如一般的AF_INETdomain下,socketaddress的定义如下:structsockaddr_in{unsignedshortintsin_family;uint16_tsin_port;structin_addrsin_addr;unsignedcharsin_zero;//未使用}structin_addr{uint32_ts_addr;}当socket的domain不同于AF_INET时,具体的地址定义又是不同的,但是整个地址结构的大小、容量都是和通用地址结构一致的。
Linux下C语言socket编程
socket编程一般是基于tcp或者udp协议来写的,你的问题很抽象,我不知道你要的是基于tcp还是udp的socket编译。我把相对难的基于tcp协议的socket编译给你吧。你想看懂我的代码需要知道tcp的三次握手机制。否则我写了注释,你看代码也有点困难。 ////服务端的代码 1 #include 《stdio.h》 2 #include 《string.h》 3 #include 《sys/socket.h》 4 #include 《unistd.h》 5 #include 《netinet/in.h》 6 #include 《sys/stat.h》 7 #include 《stdlib.h》 8 #include 《arpa/inet.h》 9 10 #define LOCAL_PORT 1234 11 #define MAX_LEN 512 12 #define MAX_NUM 5 13 14 int main(int argc, char *argv) 15 { 16 int sock_fd, sock_data; 17 int ret, len_addr; 18 char buf[MAX_LEN]; 19 ssize_t len; 20 struct sockaddr_in local_addr, remote_addr; 21 22 sock_fd = socket(AF_INET, SOCK_STREAM, 0); //创建套接字,sock_fd是套接字描述符,类似我们的身份证号码 23 if (sock_fd 《 0) 24 { 25 perror(“socket()“); 26 return sock_fd; 27 } 28 29 local_addr.sin_family = AF_INET;// 协议族,ipv4 30 local_addr.sin_port = htons(LOCAL_PORT);// 把服务器端口转换成网络字节序 31 local_addr.sin_addr.s_addr = inet_addr(“127.0.0.1“);//把字符串形式的ip转换成网络字节序 32 33 ret = bind(sock_fd, (struct sockaddr *)&local_addr, (size_t)sizeof(local_addr));// 把sock_fd和本机ip,端口邦定 34 if (ret 《 0) 35 { 36 perror(“bind()“); 37 close(sock_fd); 38 return ret; 39 } 40 41 ret = listen(sock_fd, MAX_NUM);//监听socket 42 if (ret) 43 { 44 perror(“listen()“); 45 close(sock_fd); 46 return ret; 47 } 48 49 memset(buf, 0, MAX_LEN); 50 51 len_addr = sizeof(remote_addr); 52 53 sock_data = accept(sock_fd, (struct sockaddr *)&remote_addr, (socklen_t *)&len_addr);//接受客户端的连接 54 if (ret 《 0) 55 { 56 perror(“accept()“); 57 close(sock_fd); 58 return ret; 59 } 60 61 while (1) 62 { 63 int slen; 64 len = recv(sock_data, buf, MAX_LEN, 0);//接受客户端的数据 65 if (len 《 0) 66 { 67 perror(“recv()“); 68 close(sock_data); 69 close(sock_fd); 70 return len; 71 } 72 printf(“%s\n“, buf); 73 74 slen = send(sock_data, “congratulation!“, 15, 0);//向客户端发送数据 75 if (slen 《= 0) 76 { 77 printf(“slen = %d\n“, slen); 78 perror(“send()“); 79 close(sock_data); 80 close(sock_fd); 81 return slen; 82 } 83 sleep(1); 84 } 85 86 close(sock_data); 87 close(sock_fd); 88 89 return 0; 90 }////////////客户端的代码 1 #include 《stdio.h》 2 #include 《string.h》 3 #include 《sys/socket.h》 4 #include 《unistd.h》 5 #include 《netinet/in.h》 6 #include 《sys/stat.h》 7 #include 《stdlib.h》 8 #include 《arpa/inet.h》 9 10 #define REMOTE_PORT 1234 11 #define MAX_LEN 512 12 13 int main(int argc, char *argv) 14 { 15 int sock_fd, ret; 16 int len; 17 char buf[MAX_LEN]; 18 struct sockaddr_in local_addr, remote_addr; 19 20 sock_fd = socket(AF_INET, SOCK_STREAM, 0); 21 if (sock_fd 《 0) 22 { 23 perror(“socket()“); 24 return sock_fd; 25 } 26 28 local_addr.sin_family = AF_INET; 29 local_addr.sin_addr.s_addr = htonl(INADDR_ANY); //自动获取本机的ip地址 30 local_addr.sin_port = htons(0); //随机选取可用的端口,并不是指定端口为0 31 33 remote_addr.sin_family= AF_INET; 34 remote_addr.sin_port = htons(REMOTE_PORT); 35 ret = inet_aton(“127.0.0.1“, &remote_addr.sin_addr); 36 38 ret = bind(sock_fd, (struct sockaddr *)&local_addr, sizeof(local_addr)); //把本机的ip,port和socket绑定 39 if (ret 《 0) 40 { 41 perror(“bind() !“); 42 close(sock_fd); 43 return ret; 44 } 45 47 ret = connect(sock_fd, (struct sockaddr *)&remote_addr, (socklen_t)sizeof(remote_addr)); //把本机的socket和对方的port,ip建立连接 48 if (ret 《 0) 49 { 50 perror(“connect()“); 51 close(sock_fd); 52 return ret; 53 } 54 55 memset(buf, 0, MAX_LEN); 56 57 while (1) 58 { 59 int i; 60 // len = send(sock_fd, buf, (size_t)MAX_LEN, 0); 61 len = send(sock_fd, “hello“, 6, 0); 62 if (len 《= 0) 63 { 64 perror(“send()“); 65 close(sock_fd); 66 return ret; 67 } 68 69 // printf(“%d--》bytes send!\n“, len); 70 sleep(1); 71 72 len = recv(sock_fd, buf, MAX_LEN, 0); 73 if (len 《= 0) 74 { 75 perror(“recv()“); 76 close(sock_fd); 77 return ret; 78 } 79 80 for (i = 0; i 《 len; i++) 81 { 82 printf(“%c“, buf[i]); 83 } 84 printf(“\n“); 85 } 86 87 close(sock_fd); 88 89 return 0; 90 }你把服务端和客户端这两个程序分别保存为server.c和client.c。然后编译gcc server.c -o server,gcc client .c -o client。运行时先运行服务端,用命令./server,再运行客户端,用命令./client。 注意运行命令是“点 斜杠”,“点”表示当前目录。
linux下的socket编程在哪进行
LINUX下的SOCKET编程?应该所有语言都有相应的SOCKET编程接口。C/C++、JAVA,python,RUBY,PERL,甚至是SCEME。只不过,其他几种都是跨平台的,不算是单独的LINUX下SOCKET编程。一般C语言和C++才这么说。因为LINUX下的接口和WINDOWS不一样。想知道接口有哪些的话,你得查手册或是看《UNIX环境高级编程》这类书,书上会有LINUX/UNIX的C编程接口。编译环境的话,只要是C语言编译器,LINUX支持的主要是GCC,LINUX下的开发环境IDE也默认都用GCC了,比如CODEBLOCKS、GEANY什么的。按下编译、运行按钮就行了,和WINDOWS下开发的步骤差不多,只是接口不一样。如果要用命令行的话,也不难,代码写好了,gcc 一下就可以编译了。不过,看你的水平,算了吧……要么安心学一下LINUX下编程,要么老实地用IDE。问这种问题,让人很难回答的……在哪进行,当然在LINUX下,在LINUX的C语言代码文件里,什么编译环境?C语言的编译环境……什么编译工具,C语言的编译工具,比如GCC。
LINUX网络编程中socket函数详细解释下吧
函数原型:int socket(int family,int type,int protocol); 参数解释:family指定协议簇,UNIX下(包括linux)有:AF_INET,AF_INET6,AF_LOCAL,AF_ROUTE,AF_KEY,分别是IPv4,IPv6协议,UNIX域协议,路由套接口,密钥套接口; type指定套接口类型:unix下有四种,分别是:SOCK_STREAM,SOCK_DGRAM,SOCK_SEQPACKET,SOCK_RAW。(流套接字,数据报套接字,有序分组套接字,原始套接字),SOCK_SEQPACKET已很少使用; protocol:IPPROTO_TCP,IPPROTO_UDP,IPPROTO_SCTP,分别是TCP传输协议,UDP传输协议,SCTP传输协议; 函数返回一个非负整数值,类似于文件描述符(linux内核知识),称之为套接口描述字,简称套接字。《Linux就该这么学》这本书,希望你能感受到linux系统和这本书带给你的好处及帮助。
Linux下socket编程的sockaddr_in结构体中的__SOCKADDR_COMMON (sin_);是什么意思
__SOCKADDR_COMMON();是宏定义的意思,括号里面是它的参数,这个宏定义表示的是tcp/ip协议的版本是,ipv4还是ipv6的意思,最后的那个unsignedcharsin_zero的大小为什么做减法呢,是为了保证这个结构提到大小和另一个套接字地址的结构体structsockaddr的大小一致。这么说不知道你能不能不能理解,第一个参数在实际使的时候一般是个常数。再看看别人怎么说的。