server program

转载 2011年01月13日 14:42:00
今天上午实验了java程序与c语言程序通过socket进行通信。由于没学过java,因此只是编写了C语言端的代码,java端的代码是从网上别的文章中找的,经过少量修改后与C语言端程序通信成功。

本例中C语言端作为服务器,java端作为客户端

代码如下:

/****************** server program *****************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <sys/un.h>
#include <pthread.h>
#include <arpa/inet.h>

int sockfd,newfd;
void *read_socket();

int main()
{
    int ret;
    pthread_t read_tid,write_tid;
    struct sockaddr_in server_addr;
    server_addr.sin_family=AF_INET;/*设置域为IPV4*/
    server_addr.sin_addr.s_addr=INADDR_ANY;/*绑定到 INADDR_ANY 地址*/
    server_addr.sin_port=htons(5678);/*通信端口号为5678,注意这里必须要用htons函数处理一下,不能直接写5678,否则可能会连不上*/
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if (sockfd<0)
    {
        printf("调用socket函数建立socket描述符出错!/n");
         exit(1);
    }
    printf("调用socket函数建立socket描述符成功!/n");
    ret=bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(server_addr));
    perror("server");
    if (ret<0)
    {
        printf("调用bind函数绑定套接字与地址出错!/n");
         exit(2);
    }
    printf("调用bind函数绑定套接字与地址成功!/n");
    ret=listen(sockfd,4);
    if (ret<0)
    {
        printf("调用listen函数出错,无法宣告服务器已经可以接受连接!/n");
         exit(3);
    }
    printf("调用listen函数成功,宣告服务器已经可以接受连接请求!/n");
    newfd=accept(sockfd,NULL,NULL);/*newfd连接到调用connect的客户端*/
    if (newfd<0)
    {
        printf("调用accept函数出错,无法接受连接请求,建立连接失败!/n");
         exit(4);
    }
    printf("调用accept函数成功,服务器与客户端建立连接成功!/n");
   
    /** 服务器端建立一个线程,负责从socket读取数据,当然此处并不一定非要建立一个新线程,直接在原线程中写也可以 **/
    pthread_create(&read_tid,NULL,read_socket,NULL);

   
    /********************* 令原线程睡眠 ************************/
    while(1)
    {
        sleep(10000);
    }
}

/****************** 从socket读取数据 ********************/
void *read_socket()
{
    int recv_num,recv_num_total=0;
    char recv_buf[50];
    while (1)
    {
        memset(recv_buf,0,sizeof(recv_buf));/*清空一下recv_buf缓存区*/
        recv_num=recv(newfd,recv_buf,26,0);
        if (recv_num<0)
            printf("服务器端:调用recv接收失败!/n");
        else if(recv_num>0)
        {
            recv_num_total+=recv_num;
            printf("服务器端:调用recv接收成功!本次接收到%d个字节,内容为:/"%s/"。共收到%d个字节的数据。/n",recv_num,recv_buf,recv_num_total);
            sync();
        }
        else/*收到数据为0,表明服务器与客户端的连接已经中断*/
        {
            printf("服务器端:与客户端的连接已中断,当前共收到%d个字节的数据。服务器将再次等待客户端的连接。/n",recv_num_total);
            newfd=accept(sockfd,NULL,NULL);/*当客户端退出后,再次开始接收客户端的连接*/
        }
        sleep(1);
    }
}



/****************** Client program *****************/
import java.net.*;
import java.io.*;

public class Client {
static Socket server;

public static void main(String[] args) throws Exception {
   server = new Socket(InetAddress.getLocalHost(), 5678);
   BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream()));
   PrintWriter out = new PrintWriter(server.getOutputStream());
   BufferedReader wt = new BufferedReader(new InputStreamReader(System.in));

   while (true) {
    String str = wt.readLine();
    out.println(str);
    out.flush();
    if (str.equals("end")) {
     break;
    }
   }
   server.close();
}
}


把服务器端程序存为server.c,客户端程序存为Client.java

编译:
gcc -o server -lpthread server.c
javac Client.java

在两个终端下分别运行服务端和客户端:
./server
java Client

///////////////////////// 客户端运行结果 ////////////////////////////////
hello,this is a socket test!(自己输入一些文字)
good
///////////////////////// 服务端运行结果 ////////////////////////////////
调用socket函数建立socket描述符成功!
server: Success
调用bind函数绑定套接字与地址成功!
调用listen函数成功,宣告服务器已经可以接受连接请求!
调用accept函数成功,服务器与客户端建立连接成功!
服务器端:调用recv接收成功!本次接收到26个字节,内容为:"hello,this is a socket tes"。共收到26个字节的数据。
服务器端:调用recv接收成功!本次接收到3个字节,内容为:"t!
"。共收到29个字节的数据。

服务器端:调用recv接收成功!本次接收到5个字节,内容为:"good
"。共收到34个字节的数据。

=================================

可见通信是成功的,其中客户端发送的第一条消息超过了服务端程序中规定每次读取的字节数(26个字节,在这一句里recv_num=recv(newfd,recv_buf,26,0);设定的),服务端分两次接收了该消息。

另外,客户端输入的换行符也被接收了进来,因此可以看到蓝色字体的这一条返回结果中,t!后面有一个换行,同时显示本次接收到了3个字符。

 

相关文章推荐

SQL Server 检测到基于一致性的逻辑 I/O 错误 pageid 不正确(应为 1:1772,但实际为 0:0)。在文件 'D:\Program Files\Microsoft SQL Ser

SQL Server 检测到基于一致性的逻辑 I/O 错误 pageid 不正确(应为 1:1772,但实际为 0:0)。在文件 'D:\Program Files\Microsoft SQL Ser...

Slow performance occurs when you copy data to a TCP server by using a Windows Sockets API program

Slow performance occurs when you copy data to a TCP server by using a Windows Sockets API program ...
  • pud_zha
  • pud_zha
  • 2012年08月31日 15:34
  • 792

【MySQL】C:\Program Files\MySQL\MySQL Server 5.5\data目录下找不到创建的数据库

问题: 在“C:\Program Files\MySQL\MySQL Server 5.5”目录的data文件夹里找不到创建的数据库。   解决: 1、【【其实数据存放在C盘的隐藏文件夹Pro...

Howto: Connect MySQL server using C program API under Linux or UNIX

MySQL database does support C program API just like PHP or perl.The C API code is distributed with M...

Slow performance occurs when you copy data to a TCP server by using a Windows Sockets API program

原文位置:https://support.microsoft.com/en-us/kb/823764转载部分内容,详细的见原文。SymptomsWhen you run a program that ...

“访问限制:由于对必需的库C:\Program Files\Java\jre1.8.0_20\lib\rt.jar具有一定限制,因此无法访问构造函数JFrame()”的解决方法

访问限制:由于对必需的库C:\Program Files\Java\jre1.8.0_20\lib\rt.jar具有一定限制,因此无法访问构造函数JFrame()...

iOS 开发 入门:加入iOS Developer Program (iOS开发者申请教程)

我于2012年12月23日提交加入iOS开发者计划(即iOS Developer Program,简称IDP)的申请,至2012年12月28日申请成功,扣除星期天,一共仅用了5天时间,这超出了我的意料...

Windows下的Program Files (x86)文件夹是干什么的?

今天在微博上看到有人问这个问题。在装好64位的Windows之后,能在系统盘(通常是C盘)下看到这么一个文件夹,它比我们都知道的Program Files文件夹多出来个”(x86)“的后缀。那这个带”...
  • wmtbla
  • wmtbla
  • 2016年01月11日 09:25
  • 189

直接获取Program Files目录的API

偶然间发现 SHGetSpecialFolderPath 这个API真是好东西,好多系统目录都可以直接获取了,再也不用一点点的拼装了。MSDN上的说明如下:  Syntax BOOL SH...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:server program
举报原因:
原因补充:

(最多只允许输入30个字)