linux多线程socket
A. 请教linux下socket编程中send函数如何强制其将数据发出去
在多线程编程中其中使用一个线程来accept要连接的客户端。同时在接受client的请求之后新建一个线程来进行具体的操作。其操作包括向client端发送一定字节的数据,使用send()函数来进行操作。如果在发送过程中出现任何一个client端的断线,则整个程序都会退出。
ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags);
关于Linux命令的介绍,看看《linux就该这么学》,具体关于这一章地址3w(dot)linuxprobe/chapter-02(dot)html
上面为send函数原型,在通常的使用中flags参数一般设置为0.此时如果客户端断开,继续往里边写数据的话,会引发一个信号SIGPIPE,此信号会引发线程的退出、
解决的方法:1)可以将flags参数设置为MSG_NOSIGNAL。2)设置SIG_IGN信号处理函数。
B. linux下socket编程,只需要实现服务器端能接收多个用户端发来的消息这个功能就行,求代码,最好有相应解释
这些都是自己写的,由于我很粗心调试了好久,要是有任何问题我都可以帮你解决,包教会,而且可以进一步一起完善他的功能
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/time.h>
#define BUFF_SIZE 1024
#define PORT 8888
#define LSN_NUM 10
int main()
{
int sockfd = -1;
int clt_sockfd = -1;
int i = 0, fd;
fd_set inset, tmp_inset;
struct sockaddr_in *server_addr, *client_addr;
int addr_len = sizeof(struct sockaddr_in);
int len;
char buff[BUFF_SIZE];
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 1){
printf("Create socket error!\n");
exit(0);
}else{
printf("Create socket success! sockfd = %d\n", sockfd);
}
server_addr = malloc(addr_len);
client_addr = malloc(addr_len);
memset(server_addr, 0, sizeof(server_addr));
memset(client_addr, 0, sizeof(client_addr));
server_addr->sin_family = AF_INET;
server_addr->sin_port = htons(PORT); //此处要将主机字节序转为网络字节序
server_addr->sin_addr.s_addr = INADDR_ANY;
if(bind(sockfd, (struct sockaddr*)server_addr, sizeof(struct sockaddr_in)) < 0){
printf("Bind error!\n");
exit(0);
}else{
printf("Bind success!\n");
}
if(listen(sockfd, LSN_NUM) < 0){
printf("Listen error!\n");
exit(0);
}else{
printf("Listen success!\n");
}
printf("Waiting for connect ...\n");
i = 1;
FD_ZERO(&inset);
FD_SET(sockfd, &inset);
while(1){
printf("------ The %dth turning ------- \n", i++);
tmp_inset = inset;
memset(buff, 0, BUFF_SIZE);
//select
if(select(FD_SETSIZE, &tmp_inset, NULL, NULL, NULL) <= 0){
printf("Select failed!\n");
exit(0);
}else{
printf("Select success!\n");
}//end select
for(fd = 0; fd < FD_SETSIZE; fd++){
if(FD_ISSET(fd, &tmp_inset) > 0){
printf("crrent fd: %d\n", fd);
if(sockfd == fd){
if((clt_sockfd = accept(sockfd, (struct sockaddr*)client_addr, &addr_len)) < 0){
printf("Accept error!\n");
exit(0);
}else{
printf("Get connection from %s, port: %d. socket: %d\n", \
inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port), clt_sockfd);
}
FD_SET(clt_sockfd, &inset);
}else{
if((len = recv(fd, buff, BUFF_SIZE, 0)) < 0){
printf("Recv failed!\b");
close(fd);
FD_CLR(fd, &inset);
}else if(0 == len || !strncmp("quit", buff, 4)){
printf("Clt_sockfd %d has quited!\n", clt_sockfd);
close(fd);
FD_CLR(fd, &inset);
continue;
}else{
printf("Clt_sockfd %d got message: %s\n", clt_sockfd, buff);
}
}
}
}
continue;
}
}
free(server_addr);
free(client_addr);
}
C. linux下 socket多线程 socket泄露问题
把接收输入的read函数改成recv试试。socket通信最好用recv。
D. linux中多个进程公用一个socket的问题
从设计上来说, 设计成多线程比较好,可以实现同时工作 (CUP 使用时间分片机制).至于套节字,分开来使用更简单,通信双方也能更好解析信息.如果要考虑共用一个套节字,需要使用互斥机制.
E. Linux 进程间通信方式有哪些
进程间通信(IPC,Interprocess
communication)是一组编程接口,让程序员能够协调不同的进程,使之能在一个操作系统里同时运行,并相互传递、交换信息。这使得一个程序能够在同一时间里处理许多用户的要求。因为即使只有一个用户发出要求,也可能导致一个操作系统中多个进程的运行,进程之间必须互相通话。IPC接口就提供了这种可能性。每个IPC方法均有它自己的优点和局限性,一般,对于单个程序而言使用所有的IPC方法是不常见的。
1、无名管道通信
无名管道(pipe):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用,进程的亲缘关系通常是指父子进程关系。
2、高级管道通信
高级管道(popen):将另一个程序当做一个新的进程在当前程序进程中启动,则它算是当前程序的子进程,这种方式我们称为高级管道方式。
3、有名管道通信
有名管道(named pipe):有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
4、消息队列通信
消息队列(message
queue):消息队列是由消息的链表,存放在内核中并由消息队列标识符标识,消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
5、信号量通信
信号量(semophore):信号量是一个计数器,可以用来控制多个进程对共享资源的访问,它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
6、信号
信号(sinal):信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
7、共享内存通信
共享内存(shared
memory):共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
8、套接字通信
套接字(socket):套接字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。
F. linux socket编程 双线程同时读写缓冲流时为什么fprintf被阻塞了
你用fprintf读写socket?如果是,那么应该改成send或者write因为fprintf第一个参数为FILE *而文件描述符的是int类型上就有问题。如果不是,那么会不会两个线程同时读取一个socket接口,而当时数据正好被另一个线程所读取,而导致一个线程所阻塞。
G. linux c socket 如何实现一个进程多个线程,每个线程管理多个socket连接
大家仔细看,楼主的题目还是很有难度的呢,一个进程多个线程容易实现,但是要让这些线程中每个线程都管理多个socket连接,确实比较难~~坐等高手。
不过一般都是一个线程处理一个socket连接,这种例子是:
(取自书上,仅供学习,直接编译肯定通不过,少书上其他代码)
==================================================
/* include serv06 */#include "unpthread.h"
intmain(int argc, char **argv)
{
int listenfd, connfd;
void sig_int(int);
void *doit(void *);
pthread_t tid;
socklen_t clilen, addrlen;
struct sockaddr *cliaddr;
if (argc == 2) listenfd = Tcp_listen(NULL, argv[1], &addrlen);
else if (argc == 3)
listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
else
err_quit("usage: serv06 [ <host> ] <port#>");
cliaddr = Malloc(addrlen);
Signal(SIGINT, sig_int);
for ( ; ; ) { clilen = addrlen;
connfd = Accept(listenfd, cliaddr, &clilen);
Pthread_create(&tid, NULL, &doit, (void *) connfd); }
}
void *doit(void *arg)
{
void web_child(int);
Pthread_detach(pthread_self()); web_child((int) arg);
Close((int) arg);
return(NULL);
}
/* end serv06 */
voidsig_int(int signo)
{
void pr_cpu_time(void);
pr_cpu_time(); exit(0);
}
================================================================
H. linux线程之间不能共享使用socket吗
服务器开两个线程,一个监听udp(bind函数,recvfrom函数),一个监听tcp(bing函数,listen函数,accept函数),来一个客户端请求,就再建立一个线程实现相应操作。
I. Windows Socket和Linux Socket编程的区别 ZZ
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
一、linux下的socket编程:
1、客户端执行步骤依次如下:
socket()
connect()
send()或者recv()
close()
注意的是,connect之前要填充地址结构体,IP地址转换为网络字节序,一般用inet_aton().
2、服务器端:
socket()
bind()
listen()
accpet()
recv()或者send()
close()
(ps:一般通过将send()和recv()的最后一个参数赋为0或者1来区分阻塞与非阻塞,其中0对应阻塞,1对应非阻塞)
二、windows下的网络编程:
做过windows网络编程的人都知道,微软的MFC把复杂的WinSock API函数封装到类里,这使得编写网络应用程序更容易。即windows既提供上层的网络API函数也提供底层的API函数。
1、对于采用上层的API函数而言:若采用csocket类定义一个对象obj的话,那么进行网络编程的步骤如下:
客户端:
obj.Create()
obj.Connect()
obj.Receive()或者obj.Send()
obj.Close()
服务器端:
先调用AfxSocketInit()检测协议栈安装情况
obj.Create()
obj.Listen()
obj.Accpet()
obj.Receive()或者obj.Send()
obj.Close()
2、对于采用底层的API函数而言,步骤如下:
客户端:
WSAStartup()
socket()
connect()
send()或者recv()
closesocket()
服务器端:
WSAStartup()
socket()
bind()
listen()
accpet()
send()
recv()
closesocket()
(ps:windows下CSocket类为同步方式,有阻塞现象;CASyncSocket为异步方式,无阻塞现象。)
通过以上比较可以发现:linux下的网络编程与windows下采用底层的API类似,但是也有区别:
区别一:windows下需加上WSAStartup()函数
区别二:关闭socket:linux为close(),windows为closesocket()
windows下采用上层的API,一般有CSocket和CAsynSocket这两种类型的类
这种情况以下socket函数一般的首字母大写。而底层的API不管是windows下的还是linux下的socket函数首字母都是小写的。